diff --git a/.github/workflows/assign_milestone.yml b/.github/workflows/assign_milestone.yml index 6687a239b57..e0c0b100a74 100644 --- a/.github/workflows/assign_milestone.yml +++ b/.github/workflows/assign_milestone.yml @@ -4,7 +4,9 @@ on: pull_request_target: types: [opened] -permissions: read-all +permissions: + pull-requests: write + contents: read env: GH_TOKEN: ${{ github.token }} @@ -13,18 +15,24 @@ jobs: build: name: Assign Milestone runs-on: ubuntu-24.04 - permissions: - pull-requests: write steps: - name: Checkout code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: Set up Go - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - go-version-file: go.mod + # We must explicitly checkout the base's SHA to avoid executing any code coming from + # the PR's SHA - Which would be executed in the base branch's context. + # This is really important to limit any sort of pwn requests. + ref: ${{ github.base_ref }} + persist-credentials: 'false' - name: Assign Milestone run: | - gh pr edit ${{ github.event.number }} --milestone "v$(sed -n 's/.*versionName.*\"\([[:digit:]\.]*\).*\"/\1/p' ./go/vt/servenv/version.go)" + # Ensure the content we sed from version.go is sanitized and match the correct format + VERSION=$(sed -n 's/.*versionName.*\"\([[:digit:]\.]*\).*\"/\1/p' ./go/vt/servenv/version.go) + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Invalid version format: $VERSION" + exit 1 + fi + + gh pr edit ${{ github.event.number }} --milestone "v$VERSION" diff --git a/.github/workflows/auto_approve_pr.yml b/.github/workflows/auto_approve_pr.yml index e584337f78b..e76142c659f 100644 --- a/.github/workflows/auto_approve_pr.yml +++ b/.github/workflows/auto_approve_pr.yml @@ -16,7 +16,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' + - name: Auto Approve Pull Request env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/check_make_vtadmin_authz_testgen.yml b/.github/workflows/check_make_vtadmin_authz_testgen.yml index 26543c8a948..4008bacb163 100644 --- a/.github/workflows/check_make_vtadmin_authz_testgen.yml +++ b/.github/workflows/check_make_vtadmin_authz_testgen.yml @@ -27,7 +27,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' diff --git a/.github/workflows/check_make_vtadmin_web_proto.yml b/.github/workflows/check_make_vtadmin_web_proto.yml index 1c1bf2cae4f..ae7751163e2 100644 --- a/.github/workflows/check_make_vtadmin_web_proto.yml +++ b/.github/workflows/check_make_vtadmin_web_proto.yml @@ -27,7 +27,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -59,7 +61,7 @@ jobs: uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: # node-version should match package.json - node-version: '20.12.2' + node-version: '22.13.1' - name: Install npm dependencies 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 7c98855b783..e444858ff0d 100644 --- a/.github/workflows/cluster_endtoend_12.yml +++ b/.github/workflows/cluster_endtoend_12.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (12) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml index 947d393bbbb..8afefa03c99 100644 --- a/.github/workflows/cluster_endtoend_13.yml +++ b/.github/workflows/cluster_endtoend_13.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (13) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml index aedc1bbd691..dcccc6cc187 100644 --- a/.github/workflows/cluster_endtoend_15.yml +++ b/.github/workflows/cluster_endtoend_15.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (15) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml index 9886b617d51..347eb73f919 100644 --- a/.github/workflows/cluster_endtoend_18.yml +++ b/.github/workflows/cluster_endtoend_18.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (18) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml index 5d703099a3d..f2b045e155d 100644 --- a/.github/workflows/cluster_endtoend_21.yml +++ b/.github/workflows/cluster_endtoend_21.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (21) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -121,6 +126,13 @@ jobs: # install JUnit report formatter go install github.com/vitessio/go-junit-report@HEAD + - name: Install Minio + if: steps.skip-workflow.outputs.skip-workflow == 'false' + run: | + wget https://dl.min.io/server/minio/release/linux-amd64/minio + chmod +x minio + mv minio /usr/local/bin + - 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: | diff --git a/.github/workflows/cluster_endtoend_backup_pitr.yml b/.github/workflows/cluster_endtoend_backup_pitr.yml index 1f744e85004..ae7485b874e 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (backup_pitr) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml b/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml index 6ed73f260df..1794eb893b9 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (backup_pitr_mysqlshell) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml index 9bb6a4b56f8..6d8f8808565 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (backup_pitr_xtrabackup) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Setup Percona Server for MySQL 8.0 diff --git a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml index e859749ceca..ef256dd83af 100644 --- a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml +++ b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (ers_prs_newfeatures_heavy) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_mysql80.yml b/.github/workflows/cluster_endtoend_mysql80.yml index 653db141b7d..584620fbf0f 100644 --- a/.github/workflows/cluster_endtoend_mysql80.yml +++ b/.github/workflows/cluster_endtoend_mysql80.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (mysql80) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_mysql_server_vault.yml b/.github/workflows/cluster_endtoend_mysql_server_vault.yml index 9de4aacd499..6b5ecc45495 100644 --- a/.github/workflows/cluster_endtoend_mysql_server_vault.yml +++ b/.github/workflows/cluster_endtoend_mysql_server_vault.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (mysql_server_vault) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml index 54c85944190..cb0eb7919ac 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (onlineddl_revert) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -92,6 +96,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml index 9e117ac0f04..da7b96b6578 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (onlineddl_scheduler) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -92,6 +96,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml index 5056e46d895..1d857dc2df5 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (onlineddl_vrepl) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -92,6 +96,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -149,6 +154,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard onlineddl_vrepl | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml index 3597b37ede7..bb8ff9a4b1c 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (onlineddl_vrepl_stress) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -92,6 +96,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -149,6 +154,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard onlineddl_vrepl_stress | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml index a5322578981..ea7782d6d2f 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (onlineddl_vrepl_stress_suite) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -92,6 +96,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -149,6 +154,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard onlineddl_vrepl_stress_suite | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml index 12bde509048..2671a018541 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (onlineddl_vrepl_suite) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -92,6 +96,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -149,6 +154,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard onlineddl_vrepl_suite | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml index e452d28606a..bdd8dac28a3 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (schemadiff_vrepl) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -92,6 +96,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -149,6 +154,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard schemadiff_vrepl | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml index 3e8ffce0ac5..5f445a40b46 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (tabletmanager_consul) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml index cc75ef22937..af87aec2cca 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (tabletmanager_tablegc) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml index 0837be5356e..03385c6d45d 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (tabletmanager_throttler_topo) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_topo_connection_cache.yml b/.github/workflows/cluster_endtoend_topo_connection_cache.yml index da6ee53ad53..1e27231dc74 100644 --- a/.github/workflows/cluster_endtoend_topo_connection_cache.yml +++ b/.github/workflows/cluster_endtoend_topo_connection_cache.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (topo_connection_cache) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml index a38506ddd7d..f6ab80b04da 100644 --- a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml +++ b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_across_db_versions) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_across_db_versions | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml index 283d0451a34..9b21f46e054 100644 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_basic.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_basic) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_basic | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml index b316c075614..95cf9a15214 100644 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_cellalias) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_cellalias | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml index 48f506709e7..6cca449201d 100644 --- a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml +++ b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_copy_parallel) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_copy_parallel | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml index a1293e3688e..2890abaef4c 100644 --- a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml +++ b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_foreign_key_stress) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_foreign_key_stress | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml index 2013d89a83d..4cf82c81f4b 100644 --- a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml +++ b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_mariadb_to_mysql) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_mariadb_to_mysql | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate.yml b/.github/workflows/cluster_endtoend_vreplication_migrate.yml index e7a8a8cb5ce..d0667c30ba4 100644 --- a/.github/workflows/cluster_endtoend_vreplication_migrate.yml +++ b/.github/workflows/cluster_endtoend_vreplication_migrate.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_migrate) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_migrate | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml index c0c80a8dc61..326591fe820 100644 --- a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml +++ b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_multi_tenant) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_multi_tenant | tee -a output.txt | go-junit-report -set-exit-code > report.xml 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 0b80b82fd7f..0124cd03832 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_partial_movetables_and_materialize) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_partial_movetables_and_materialize | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml index fcbe7057b4c..a8285f109a3 100644 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_v2.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_v2) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_v2 | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vreplication_vtctldclient_vdiff2_movetables_tz.yml b/.github/workflows/cluster_endtoend_vreplication_vtctldclient_vdiff2_movetables_tz.yml index 40f2002f9a3..0b599116e4c 100644 --- a/.github/workflows/cluster_endtoend_vreplication_vtctldclient_vdiff2_movetables_tz.yml +++ b/.github/workflows/cluster_endtoend_vreplication_vtctldclient_vdiff2_movetables_tz.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vreplication_vtctldclient_vdiff2_movetables_tz) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo @@ -166,6 +171,10 @@ jobs: binlog-transaction-compression=ON EOF + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker=false -follow -shard vreplication_vtctldclient_vdiff2_movetables_tz | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/cluster_endtoend_vstream.yml b/.github/workflows/cluster_endtoend_vstream.yml index acfefb40758..c6a6bbb515f 100644 --- a/.github/workflows/cluster_endtoend_vstream.yml +++ b/.github/workflows/cluster_endtoend_vstream.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vstream) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtbackup.yml b/.github/workflows/cluster_endtoend_vtbackup.yml index 947598bc307..38ff7e41cbc 100644 --- a/.github/workflows/cluster_endtoend_vtbackup.yml +++ b/.github/workflows/cluster_endtoend_vtbackup.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtbackup) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml index c6f8712a35a..6ce9887700c 100644 --- a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtctlbackup_sharded_clustertest_heavy) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml index 2cd81fe04ef..840e4c496b9 100644 --- a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml +++ b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_concurrentdml) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml index 19620d9e3a2..39f03784840 100644 --- a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml +++ b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_foreignkey_stress) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_gen4.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml index 06961af4ee7..f62a830ea73 100644 --- a/.github/workflows/cluster_endtoend_vtgate_gen4.yml +++ b/.github/workflows/cluster_endtoend_vtgate_gen4.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_gen4) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml index e0b21df421a..59db477d840 100644 --- a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_general_heavy) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_godriver.yml b/.github/workflows/cluster_endtoend_vtgate_godriver.yml index 23c9da550c2..b0a32a13b6f 100644 --- a/.github/workflows/cluster_endtoend_vtgate_godriver.yml +++ b/.github/workflows/cluster_endtoend_vtgate_godriver.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_godriver) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml index f5d1850aca3..bca24b0a3bc 100644 --- a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml +++ b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_partial_keyspace) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_plantests.yml b/.github/workflows/cluster_endtoend_vtgate_plantests.yml new file mode 100644 index 00000000000..9c2c905564d --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_plantests.yml @@ -0,0 +1,171 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_plantests) +on: [push, pull_request] +concurrency: + group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_plantests)') + 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: + timeout-minutes: 60 + name: Run endtoend tests on Cluster (vtgate_plantests) + runs-on: ubuntu-24.04 + + 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' + + - name: Check for changes in relevant files + if: steps.skip-workflow.outputs.skip-workflow == 'false' + uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 + id: changes + with: + token: '' + filters: | + end_to_end: + - 'test/config.json' + - '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_vtgate_plantests.yml' + + - name: Set up Go + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + with: + go-version-file: go.mod + + - name: Set up python + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + + - 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' + timeout-minutes: 10 + 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.33-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 + + # We have to install this old version of libaio1 in case we end up testing with MySQL 5.7. See also: + # https://bugs.launchpad.net/ubuntu/+source/libaio/+bug/2067501 + curl -L -O http://mirrors.kernel.org/ubuntu/pool/main/liba/libaio/libaio1_0.3.112-13build1_amd64.deb + sudo dpkg -i libaio1_0.3.112-13build1_amd64.deb + # libtinfo5 is also needed for older MySQL 5.7 builds. + curl -L -O http://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb + sudo dpkg -i libtinfo5_6.3-2ubuntu0.1_amd64.deb + + # Install everything else we need, and configure + sudo apt-get -qq install -y mysql-server mysql-shell mysql-client make unzip g++ etcd-client etcd-server curl git wget eatmydata xz-utils libncurses6 + + 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 vtgate_plantests | 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 + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 + with: + paths: "report.xml" + show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_queries.yml b/.github/workflows/cluster_endtoend_vtgate_queries.yml index 80462086a57..abd4ca2d713 100644 --- a/.github/workflows/cluster_endtoend_vtgate_queries.yml +++ b/.github/workflows/cluster_endtoend_vtgate_queries.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_queries) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml index 686db1e12ab..a6f24c0f983 100644 --- a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml +++ b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_readafterwrite) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml index 0f4ae20b0a7..72e7405e537 100644 --- a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml +++ b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_reservedconn) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml index 2dca36298e1..c954ac7d455 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_schema) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml index 711f38253cb..fa57ba09a30 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_schema_tracker) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml index 55996d7fa86..520a5a72ca7 100644 --- a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml +++ b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_tablet_healthcheck_cache) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml index f47e0a8dd63..c8151df7b79 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_topo) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml index 1b62ac79041..ebde8c3d0d9 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_topo_consul) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml index f88d3b9af3a..a3e11cb8eb9 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_topo_etcd) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml index 9ae7b465695..1014508be2a 100644 --- a/.github/workflows/cluster_endtoend_vtgate_transaction.yml +++ b/.github/workflows/cluster_endtoend_vtgate_transaction.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_transaction) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml index d348606dc31..fa922f575e6 100644 --- a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml +++ b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_unsharded) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml index 16bdee60217..36c75f52d05 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_vindex_heavy) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml index fb176119769..d0dd3c7c917 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vschema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vschema.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtgate_vschema) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml index 92c2ea3d5d7..dbaa4b04143 100644 --- a/.github/workflows/cluster_endtoend_vtorc.yml +++ b/.github/workflows/cluster_endtoend_vtorc.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vtorc) runs-on: ubuntu-24.04 @@ -54,7 +55,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -64,6 +67,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -100,6 +104,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml index 9868c382a69..ea1b662e1be 100644 --- a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml +++ b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (vttablet_prscomplex) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Get key to latest MySQL repo diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml index 26dbfea2def..8ae98fc9ffd 100644 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ b/.github/workflows/cluster_endtoend_xb_backup.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (xb_backup) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Setup Percona Server for MySQL 8.0 diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml index 43360690d6b..d617e99dcb9 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -15,6 +15,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on Cluster (xb_recovery) runs-on: ubuntu-24.04 @@ -45,7 +46,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -91,6 +95,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | # Setup Percona Server for MySQL 8.0 diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index fc30974212b..35517c4f6c5 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -13,7 +13,9 @@ jobs: steps: - name: Check out code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in files relevant to code coverage uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 @@ -111,7 +113,7 @@ jobs: - name: Upload coverage reports to codecov.io if: steps.changes.outputs.changed_files == 'true' - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # https://github.com/codecov/codecov-action/releases/tag/v5.0.7 with: fail_ci_if_error: true verbose: true diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml index c523e34c697..864a29898fe 100644 --- a/.github/workflows/codeql_analysis.yml +++ b/.github/workflows/codeql_analysis.yml @@ -27,7 +27,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Set up Go uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 @@ -47,6 +49,7 @@ jobs: # queries: security-extended,security-and-quality - name: Get base dependencies + timeout-minutes: 10 run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update # Uninstall any previously installed MySQL first diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 424cc5bfe15..1d88b034164 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -7,22 +7,25 @@ on: release: types: [created] -permissions: read-all +permissions: + contents: write + actions: read jobs: build: name: Create Release runs-on: ubuntu-24.04 - permissions: - contents: write steps: - name: Check out code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Set up Go uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: go.mod + cache: 'false' - name: Tune the OS run: | @@ -33,14 +36,36 @@ jobs: sudo apt-get update sudo apt-get install -y make ruby ruby-dev go mod download - sudo gem install fpm + + # We use fpm to package our artifacts, we want to pin the version we use and + # ensure the checksum of the package matches the one published on the package's webpage. + # https://rubygems.org/gems/fpm/versions + - name: Get fpm + run: | + FPM_VERSION=1.16.0 + gem fetch fpm -v $FPM_VERSION + + # Reviewers: The expected checksum MUST ALWAYS match the one published on this website: + # https://rubygems.org/gems/fpm/versions + EXPECTED_CHECKSUM="d9eafe613cfbdf9d3b8ef2e321e194cd0a2d300ce37f716c0be1b3a42b7db5df" + + GOT_CHECKSUM=$(sha256sum fpm-$FPM_VERSION.gem | awk '{print $1}') + + if [[ "$GOT_CHECKSUM" != "$EXPECTED_CHECKSUM" ]]; then + echo "Checksum validation failed" + echo "Expected: $EXPECTED_CHECKSUM" + echo "Got: $GOT_CHECKSUM" + exit 1 + fi + + sudo gem install fpm-$FPM_VERSION.gem - name: Make Packages run: | ./tools/make-release-packages.sh - name: Upload Files - uses: csexton/release-asset-action@master + uses: csexton/release-asset-action@3567794e918fa3068116688122a76cdeb57b5f09 # v3.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} pattern: "releases/*.{tar.gz,rpm,deb}" diff --git a/.github/workflows/docker_build_images.yml b/.github/workflows/docker_build_images.yml index 2024d677205..a9d4ed2ceeb 100644 --- a/.github/workflows/docker_build_images.yml +++ b/.github/workflows/docker_build_images.yml @@ -22,11 +22,13 @@ jobs: strategy: fail-fast: true matrix: - branch: [ mysql80 ] + branch: [ mysql80, mysql84 ] steps: - name: Check out code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Login to Docker Hub uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 @@ -40,7 +42,7 @@ jobs: - name: Build and push on main if: startsWith(github.ref, 'refs/tags/') == false - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: . file: ${{ env.DOCKERFILE }} @@ -61,7 +63,7 @@ jobs: - name: Build and push on tags if: startsWith(github.ref, 'refs/tags/') - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: . file: ${{ env.DOCKERFILE }} @@ -76,11 +78,13 @@ jobs: strategy: fail-fast: true matrix: - branch: [ latest, percona80 ] + branch: [ latest, mysql84, percona80 ] steps: - name: Check out code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Login to Docker Hub uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 @@ -98,7 +102,7 @@ jobs: - name: Build and push on main if: startsWith(github.ref, 'refs/tags/') == false - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: . file: ${{ env.DOCKERFILE }} @@ -123,7 +127,7 @@ jobs: - name: Build and push on tags if: startsWith(github.ref, 'refs/tags/') - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: . file: ${{ env.DOCKERFILE }} @@ -145,7 +149,9 @@ jobs: steps: - name: Check out code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Login to Docker Hub uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 @@ -159,7 +165,7 @@ jobs: - name: Build and push on main latest tag if: startsWith(github.ref, 'refs/tags/') == false && matrix.debian == 'bookworm' - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: ${{ env.DOCKER_CTX }} push: true @@ -170,7 +176,7 @@ jobs: - name: Build and push on main debian specific tag if: startsWith(github.ref, 'refs/tags/') == false - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: ${{ env.DOCKER_CTX }} push: true @@ -202,7 +208,7 @@ jobs: # Build and Push component image to DOCKER_TAG, applies to both debian version - name: Build and push on tags using Debian extension if: startsWith(github.ref, 'refs/tags/') - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: ${{ env.DOCKER_CTX }} push: true @@ -215,7 +221,7 @@ jobs: # It is fine to build a second time here when "matrix.debian == 'bookworm'" as we have cached the first build already - name: Build and push on tags without Debian extension if: startsWith(github.ref, 'refs/tags/') && matrix.debian == 'bookworm' - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: context: ${{ env.DOCKER_CTX }} push: true diff --git a/.github/workflows/docker_test_cluster_25.yml b/.github/workflows/docker_test_cluster.yml similarity index 85% rename from .github/workflows/docker_test_cluster_25.yml rename to .github/workflows/docker_test_cluster.yml index 34463ce3830..6c6310a9efc 100644 --- a/.github/workflows/docker_test_cluster_25.yml +++ b/.github/workflows/docker_test_cluster.yml @@ -1,10 +1,10 @@ -name: docker_test_cluster_25 +name: docker_test_cluster on: [push, pull_request] permissions: read-all jobs: build: - name: Docker Test Cluster 25 + name: Docker Test Cluster runs-on: ubuntu-24.04 steps: @@ -27,7 +27,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -37,6 +39,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'test.go' - 'Makefile' @@ -48,7 +51,7 @@ jobs: - 'config/**' - 'bootstrap.sh' - 'docker/**' - - '.github/workflows/docker_test_cluster_25.yml' + - '.github/workflows/docker_test_cluster.yml' - name: Set up Go if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -64,4 +67,4 @@ jobs: - name: Run tests which require docker - 2 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | - go run test.go -docker=true --follow -shard 25 + go run test.go -docker=true --follow -shard docker_cluster diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index 50e1e4b9485..abd7355f078 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -26,7 +26,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index f061e8bee68..71b84f7acdc 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -26,7 +26,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' diff --git a/.github/workflows/docker_test_cluster_10.yml b/.github/workflows/java_docker_test.yml similarity index 85% rename from .github/workflows/docker_test_cluster_10.yml rename to .github/workflows/java_docker_test.yml index 10a7c1551c0..adb87922dfc 100644 --- a/.github/workflows/docker_test_cluster_10.yml +++ b/.github/workflows/java_docker_test.yml @@ -1,10 +1,10 @@ -name: docker_test_cluster_10 +name: java_docker_test on: [push, pull_request] permissions: read-all jobs: build: - name: Docker Test Cluster 10 + name: Java Docker Test runs-on: ubuntu-24.04 steps: @@ -27,7 +27,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -37,6 +39,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'test.go' - 'Makefile' @@ -48,7 +51,8 @@ jobs: - 'config/**' - 'bootstrap.sh' - 'docker/**' - - '.github/workflows/docker_test_cluster_10.yml' + - 'java/**' + - '.github/workflows/java_docker_test.yml' - name: Set up Go if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -65,4 +69,4 @@ jobs: - name: Run tests which require docker - 1 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | - go run test.go -docker=true --follow -shard 10 + go run test.go -docker=true --follow -shard java diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index fc9724aa6ac..ef3569bfb86 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -30,7 +30,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -40,6 +42,7 @@ jobs: token: '' filters: | examples: + - 'test/config.json' - 'go/**/*.go' - 'test.go' - 'Makefile' diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index c17f43eec11..ed190884446 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -30,7 +30,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -40,6 +42,7 @@ jobs: token: '' filters: | examples: + - 'test/config.json' - 'go/**/*.go' - 'test.go' - 'Makefile' diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index b879ec8c144..de90706da27 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -53,7 +53,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif @@ -62,6 +62,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 with: sarif_file: results.sarif diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index cd2cce93827..b7f14688b95 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -31,7 +31,9 @@ jobs: - name: Checkout code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Run FOSSA scan and upload build data uses: fossa-contrib/fossa-action@v3 @@ -228,7 +230,7 @@ jobs: uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: # make proto requires newer node than the pre-installed one - node-version: '20.12.2' + node-version: '22.13.1' - name: check_make_proto if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index 8ffb74bd2cb..77f47a6c083 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -43,7 +43,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -53,6 +55,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' diff --git a/.github/workflows/unit_race_evalengine.yml b/.github/workflows/unit_race_evalengine.yml index d6d248f066e..9654209f2a9 100644 --- a/.github/workflows/unit_race_evalengine.yml +++ b/.github/workflows/unit_race_evalengine.yml @@ -43,7 +43,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -53,6 +55,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' diff --git a/.github/workflows/unit_test_evalengine_mysql57.yml b/.github/workflows/unit_test_evalengine_mysql57.yml index ecc366b38fe..eea3a5aad57 100644 --- a/.github/workflows/unit_test_evalengine_mysql57.yml +++ b/.github/workflows/unit_test_evalengine_mysql57.yml @@ -45,7 +45,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +57,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' @@ -163,6 +166,9 @@ jobs: export NOVTADMINBUILD=1 export VTEVALENGINETEST="1" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql57" eatmydata -- make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/unit_test_evalengine_mysql80.yml b/.github/workflows/unit_test_evalengine_mysql80.yml index e6e802b52d8..f48e224808d 100644 --- a/.github/workflows/unit_test_evalengine_mysql80.yml +++ b/.github/workflows/unit_test_evalengine_mysql80.yml @@ -45,7 +45,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +57,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' @@ -153,6 +156,9 @@ jobs: export NOVTADMINBUILD=1 export VTEVALENGINETEST="1" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql80" eatmydata -- make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/unit_test_evalengine_mysql84.yml b/.github/workflows/unit_test_evalengine_mysql84.yml index 46736dac349..6b373d96812 100644 --- a/.github/workflows/unit_test_evalengine_mysql84.yml +++ b/.github/workflows/unit_test_evalengine_mysql84.yml @@ -45,7 +45,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +57,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' @@ -153,6 +156,9 @@ jobs: export NOVTADMINBUILD=1 export VTEVALENGINETEST="1" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql84" eatmydata -- make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index 3eaf02d1538..3644170ebdc 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -45,7 +45,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +57,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' @@ -163,6 +166,9 @@ jobs: export NOVTADMINBUILD=1 export VTEVALENGINETEST="0" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql57" eatmydata -- make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index c036e6dd477..18bfa546124 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -45,7 +45,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +57,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' @@ -153,6 +156,9 @@ jobs: export NOVTADMINBUILD=1 export VTEVALENGINETEST="0" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql80" eatmydata -- make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/unit_test_mysql84.yml b/.github/workflows/unit_test_mysql84.yml index 84447ce390b..10b3c2b8a6c 100644 --- a/.github/workflows/unit_test_mysql84.yml +++ b/.github/workflows/unit_test_mysql84.yml @@ -45,7 +45,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +57,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' @@ -153,6 +156,9 @@ jobs: export NOVTADMINBUILD=1 export VTEVALENGINETEST="0" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql84" eatmydata -- make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/.github/workflows/update_golang_dependencies.yml b/.github/workflows/update_golang_dependencies.yml index 33c5157097c..e2a3e7bd847 100644 --- a/.github/workflows/update_golang_dependencies.yml +++ b/.github/workflows/update_golang_dependencies.yml @@ -22,9 +22,10 @@ jobs: go-version-file: go.mod - name: Check out code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: main + persist-credentials: 'false' - name: Upgrade the Golang Dependencies id: detect-and-update diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index ad5dceeafa5..1948caf4b82 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Check out code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ matrix.branch }} diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index a56aad2f523..9fc4c00e18e 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -35,9 +35,10 @@ jobs: - name: Check out commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +56,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -72,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -84,6 +86,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo apt-get update @@ -107,9 +110,10 @@ jobs: # Checkout to the last release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -129,7 +133,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 7ee6c2db799..6586cca7a13 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -25,9 +25,10 @@ jobs: fi - name: Check out commit's code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-next-release-ref @@ -57,6 +58,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -86,6 +88,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo apt-get update @@ -109,9 +112,10 @@ jobs: # Checkout to the next release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the next release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -131,7 +135,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 00aab1b78ff..7ca2c3ebbea 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -38,9 +38,10 @@ jobs: # Checkout to this build's commit - name: Checkout to commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-previous-release-ref @@ -58,6 +59,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -76,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -88,6 +90,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -129,9 +132,10 @@ jobs: # Checkout to the last release of Vitess - name: Checkout to the other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -151,7 +155,9 @@ jobs: # Checkout to this build's commit - name: Checkout to commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 768268271a1..96715bbe9de 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -27,9 +27,10 @@ jobs: # Checkout to this build's commit - name: Checkout to commit's code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-next-release-ref @@ -59,6 +60,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -89,6 +91,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -130,9 +133,10 @@ jobs: # Checkout to the next release of Vitess - name: Checkout to the other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the next release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -152,7 +156,9 @@ jobs: # Checkout to this build's commit - name: Checkout to commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml index 72426e70a61..03dd28c2e2a 100644 --- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Online DDL flow runs-on: gh-hosted-runners-16cores-1-24.04 @@ -38,9 +39,10 @@ jobs: - name: Check out commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -50,6 +52,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -83,7 +86,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -95,6 +98,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -127,9 +131,10 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -150,9 +155,10 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the next release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -173,7 +179,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 5ac1a55334c..e155be9f389 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -38,9 +39,10 @@ jobs: - name: Check out commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-previous-release-ref @@ -58,6 +60,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -75,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -87,6 +90,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -135,9 +139,10 @@ jobs: # Checkout to the last release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release 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_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml new file mode 100644 index 00000000000..2d58d4c8fae --- /dev/null +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml @@ -0,0 +1,217 @@ +name: Query Serving (Queries - 2) - Upgrade Downgrade Testing +on: + push: + pull_request: + +concurrency: + group: format('{0}-{1}', ${{ github.ref }}, 'Upgrade Downgrade Testing Query Serving (Queries - 2)') + cancel-in-progress: true + +permissions: read-all + +# This test ensures that our end-to-end tests work using Vitess components +# (vtgate, vttablet, etc) built on different versions. + +jobs: + + upgrade_downgrade_test: + timeout-minutes: 60 + name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) + runs-on: gh-hosted-runners-16cores-1-24.04 + + 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + persist-credentials: 'false' + + - 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: Check for changes in relevant files + if: steps.skip-workflow.outputs.skip-workflow == 'false' + uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 + id: changes + with: + token: '' + filters: | + end_to_end: + - 'test/config.json' + - 'go/**' + - 'go/**/*.go' + - 'test.go' + - 'Makefile' + - 'build.env' + - 'go.sum' + - 'go.mod' + - 'proto/*.proto' + - 'tools/**' + - 'config/**' + - 'bootstrap.sh' + - '.github/workflows/upgrade_downgrade_test_query_serving_queries.yml' + + - name: Set up Go + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + with: + go-version: 1.23.5 + + - name: Set up python + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + + - 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 + timeout-minutes: 10 + 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.33-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-client etcd-server 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 + + # Build current commit's binaries + - 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 + NOVTADMINBUILD=1 make build + mkdir -p /tmp/vitess-build-current/ + cp -R bin /tmp/vitess-build-current/ + rm -Rf bin/* + + # Checkout to the last release of Vitess + - name: Check out other 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' + + - 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 + NOVTADMINBUILD=1 make build + mkdir -p /tmp/vitess-build-other/ + cp -R bin /tmp/vitess-build-other/ + rm -Rf bin/* + + - name: Convert ErrorContains checks to Error checks + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} + + find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} + + + # Swap the binaries in the bin. Use vtgate version n-1 and keep vttablet at version n + - name: Use last release's VTGate + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + source build.env + + cp -r /tmp/vitess-build-current/bin/* $PWD/bin/ + rm -f $PWD/bin/vtgate + cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate + vtgate --version + + # Running a test with vtgate at version n-1 and vttablet/vtctld at version n + - name: Run query serving tests (vtgate=N-1, vttablet=N, vtctld=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 + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2 + + # Swap the binaries again. This time, vtgate will be at version n, and vttablet/vtctld will be at version n-1 + - name: Use current version VTGate, and other version VTTablet/VTctld + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + source build.env + + rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld + cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate + + cp /tmp/vitess-build-other/bin/vtctld $PWD/bin + cp /tmp/vitess-build-other/bin/vtctldclient $PWD/bin + cp /tmp/vitess-build-other/bin/vtctl $PWD/bin + cp /tmp/vitess-build-other/bin/vtctlclient $PWD/bin + + cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet + cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl + cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld + vtgate --version + vttablet --version + + # Running a test with vtgate at version n and vttablet/vtctld at version n-1 + - name: Run query serving tests (vtgate=N, vttablet=N-1, vtctld=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 + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2 diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml new file mode 100644 index 00000000000..32a00022737 --- /dev/null +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml @@ -0,0 +1,215 @@ +name: Query Serving (Queries - 2) Next Release - Upgrade Downgrade Testing +on: + push: + pull_request: + +concurrency: + group: format('{0}-{1}', ${{ github.ref }}, 'Upgrade Downgrade Testing Query Serving (Queries - 2) Next Release') + cancel-in-progress: true + +permissions: read-all + +# This test ensures that our end-to-end tests work using Vitess components +# (vtgate, vttablet, etc) built on different versions. + +jobs: + + upgrade_downgrade_test: + timeout-minutes: 60 + name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) Next Release + runs-on: gh-hosted-runners-16cores-1-24.04 + + 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 out commit's code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + persist-credentials: 'false' + + - name: Set output with latest release branch + 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: 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 + if [[ "${{steps.output-next-release-ref.outputs.next_release_ref}}" == "" ]]; then + skip='true' + fi + echo Skip ${skip} + echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT + + - name: Check for changes in relevant files + if: steps.skip-workflow.outputs.skip-workflow == 'false' + uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 + id: changes + with: + token: '' + filters: | + end_to_end: + - 'test/config.json' + - 'go/**' + - 'go/**/*.go' + - 'test.go' + - 'Makefile' + - 'build.env' + - 'go.sum' + - 'go.mod' + - 'proto/*.proto' + - 'tools/**' + - 'config/**' + - 'bootstrap.sh' + - '.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml' + + - name: Set up Go + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + with: + go-version-file: go.mod + + - name: Set up python + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + + - 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 + timeout-minutes: 10 + 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 nextly 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.33-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-client etcd-server 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 + + # Checkout to the next release of Vitess + - name: Check out other 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' + + - 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-other/ + cp -R bin /tmp/vitess-build-other/ + 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' + + - 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 + NOVTADMINBUILD=1 make build + mkdir -p /tmp/vitess-build-current/ + cp -R bin /tmp/vitess-build-current/ + + - name: Convert ErrorContains checks to Error checks + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} + + find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} + + + # Swap the binaries in the bin. Use vtgate version n+1 and keep vttablet at version n + - name: Use next release's VTGate + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + source build.env + rm -f $PWD/bin/vtgate + cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate + vtgate --version + + # Running a test with vtgate at version n+1 and vttablet at version n + - name: Run query serving tests (vtgate=N+1, vttablet=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 + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2 + + # Swap the binaries again. This time, vtgate will be at version n, and vttablet will be at version n+1 + - name: Use current version VTGate, and other version VTTablet + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + source build.env + + rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld + cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate + cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet + cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl + cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld + vtgate --version + vttablet --version + + # Running a test with vtgate at version n and vttablet at version n+1 + - name: Run query serving tests (vtgate=N, vttablet=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 + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2 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 c65fff08c52..faea680e0a8 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 @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries) Next Release runs-on: gh-hosted-runners-16cores-1-24.04 @@ -27,9 +28,10 @@ jobs: fi - name: Check out commit's code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-next-release-ref @@ -59,6 +61,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -88,6 +91,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -120,9 +124,10 @@ jobs: # Checkout to the next release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the next release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -142,7 +147,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 4b5fad0ab29..8c82838594d 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Schema) runs-on: gh-hosted-runners-16cores-1-24.04 @@ -38,9 +39,10 @@ jobs: - name: Check out commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-previous-release-ref @@ -58,6 +60,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -75,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -87,6 +90,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -119,9 +123,10 @@ jobs: # Checkout to the last release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -141,7 +146,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 6157079db6f..2450547966e 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 @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Schema) Next Release runs-on: gh-hosted-runners-16cores-1-24.04 @@ -27,9 +28,10 @@ jobs: fi - name: Check out commit's code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-next-release-ref @@ -59,6 +61,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -88,6 +91,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -120,9 +124,10 @@ jobs: # Checkout to the next release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the next release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -142,7 +147,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 931d9174c31..d25a772e423 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent New Vtctl runs-on: gh-hosted-runners-16cores-1-24.04 @@ -27,9 +28,10 @@ jobs: fi - name: Check out commit's code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-next-release-ref @@ -59,6 +61,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -88,6 +91,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -120,9 +124,10 @@ jobs: # Checkout to the next release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the next release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -142,7 +147,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 d77b7be53b3..62cb6bf2018 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent New VTTablet runs-on: gh-hosted-runners-16cores-1-24.04 @@ -27,9 +28,10 @@ jobs: fi - name: Check out commit's code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-next-release-ref @@ -59,6 +61,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -88,6 +91,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -127,9 +131,10 @@ jobs: # Checkout to the next release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the next release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -149,7 +154,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 701025d7ecc..b3e2cf6451e 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent Old Vtctl runs-on: gh-hosted-runners-16cores-1-24.04 @@ -38,9 +39,10 @@ jobs: - name: Check out commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-previous-release-ref @@ -58,6 +60,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -75,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -87,6 +90,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -119,9 +123,10 @@ jobs: # Checkout to the last release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -141,7 +146,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit 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 8b121d4af10..fe0702b2fff 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: upgrade_downgrade_test: + timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent Old VTTablet runs-on: gh-hosted-runners-16cores-1-24.04 @@ -38,9 +39,10 @@ jobs: - name: Check out commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch id: output-previous-release-ref @@ -58,6 +60,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -75,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -87,6 +90,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo DEBIAN_FRONTEND="noninteractive" apt-get update @@ -119,9 +123,10 @@ jobs: # Checkout to the last release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -141,7 +146,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml index f12e323654e..cb950d43e4e 100644 --- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml +++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml @@ -35,9 +35,10 @@ jobs: - name: Check out commit's code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + persist-credentials: 'false' - name: Set output with latest release branch if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +56,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**' - 'go/**/*.go' - 'test.go' @@ -72,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.22.7 + go-version: 1.23.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -84,6 +86,7 @@ jobs: sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - name: Get base dependencies + timeout-minutes: 10 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' run: | sudo apt-get update @@ -107,9 +110,10 @@ jobs: # Checkout to the last release of Vitess - name: Check out other 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + persist-credentials: 'false' - name: Get dependencies for the last release if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' @@ -129,7 +133,9 @@ jobs: # 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@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Get dependencies for this commit if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/vitess_tester_vtgate.yml b/.github/workflows/vitess_tester_vtgate.yml index 7d5cf89a3ec..f9429909374 100644 --- a/.github/workflows/vitess_tester_vtgate.yml +++ b/.github/workflows/vitess_tester_vtgate.yml @@ -45,7 +45,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -55,6 +57,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/vtgate/vitess_tester/**' diff --git a/.github/workflows/vtadmin_web_build.yml b/.github/workflows/vtadmin_web_build.yml index 822fa8a0920..1c3f4a93175 100644 --- a/.github/workflows/vtadmin_web_build.yml +++ b/.github/workflows/vtadmin_web_build.yml @@ -35,14 +35,16 @@ jobs: echo Skip ${skip} echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 if: steps.skip-workflow.outputs.skip-workflow == 'false' + with: + persist-credentials: 'false' - uses: actions/setup-node@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' with: # node-version should match package.json - node-version: '20.12.2' + node-version: '22.13.1' - name: Install dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' diff --git a/.github/workflows/vtadmin_web_lint.yml b/.github/workflows/vtadmin_web_lint.yml index 694c24734a6..403b978dd98 100644 --- a/.github/workflows/vtadmin_web_lint.yml +++ b/.github/workflows/vtadmin_web_lint.yml @@ -35,14 +35,16 @@ jobs: echo Skip ${skip} echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 if: steps.skip-workflow.outputs.skip-workflow == 'false' + with: + persist-credentials: 'false' - uses: actions/setup-node@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' with: # node-version should match package.json - node-version: '20.12.2' + node-version: '22.13.1' - name: Install dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' diff --git a/.github/workflows/vtadmin_web_unit_tests.yml b/.github/workflows/vtadmin_web_unit_tests.yml index 72a887c1926..6665936175f 100644 --- a/.github/workflows/vtadmin_web_unit_tests.yml +++ b/.github/workflows/vtadmin_web_unit_tests.yml @@ -35,14 +35,16 @@ jobs: echo Skip ${skip} echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 if: steps.skip-workflow.outputs.skip-workflow == 'false' + with: + persist-credentials: 'false' - uses: actions/setup-node@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' with: # node-version should match package.json - node-version: '20.12.2' + node-version: '22.13.1' - name: Install dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml index fb5ae87c101..0d27d43b959 100644 --- a/.github/workflows/vtop_example.yml +++ b/.github/workflows/vtop_example.yml @@ -36,7 +36,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' diff --git a/Makefile b/Makefile index 13f7fde28e0..aeb1955bf18 100644 --- a/Makefile +++ b/Makefile @@ -284,9 +284,9 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # Please read docker/README.md to understand the different available images. # This rule builds the bootstrap images for all flavors. -DOCKER_IMAGES_FOR_TEST = mysql80 percona80 +DOCKER_IMAGES_FOR_TEST = mysql80 mysql84 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=39 +BOOTSTRAP_VERSION=41 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 @@ -322,7 +322,7 @@ define build_docker_image fi endef -DOCKER_LITE_SUFFIX = percona80 +DOCKER_LITE_SUFFIX = mysql84 percona80 DOCKER_LITE_TARGETS = $(addprefix docker_lite_,$(DOCKER_LITE_SUFFIX)) $(DOCKER_LITE_TARGETS): docker_lite_%: ${call build_docker_image,docker/lite/Dockerfile.$*,vitess/lite:$*} diff --git a/build.env b/build.env index 58abbf41d1b..12431842b6e 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.23.4 || echo "Go version reported: `go version`. Version 1.23.4+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.23.5 || echo "Go version reported: `go version`. Version 1.23.5+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/changelog/19.0/19.0.9/changelog.md b/changelog/19.0/19.0.9/changelog.md new file mode 100644 index 00000000000..5b56b4b2afb --- /dev/null +++ b/changelog/19.0/19.0.9/changelog.md @@ -0,0 +1,49 @@ +# Changelog of Vitess v19.0.9 + +### Bug fixes +#### Query Serving + * [release-19.0] Fix Data race in semi-join (#17417) [#17445](https://github.com/vitessio/vitess/pull/17445) + * [release-19.0] Always return a valid timezone in cursor (#17546) [#17549](https://github.com/vitessio/vitess/pull/17549) +#### VReplication + * [release-19.0] LookupVindex: fix CLI to allow creating non-unique lookups with single column (#17301) [#17347](https://github.com/vitessio/vitess/pull/17347) + * [release-19.0] SwitchTraffic: use separate context while canceling a migration (#17340) [#17364](https://github.com/vitessio/vitess/pull/17364) + * [release-19.0] LookupVindex bug fix: Fix typos from PR 17301 (#17423) [#17436](https://github.com/vitessio/vitess/pull/17436) + * [Direct PR] Fix merge issue in backport [#17509](https://github.com/vitessio/vitess/pull/17509) + * [release-19.0] Tablet picker: Handle the case where a primary tablet is not setup for a shard (#17573) [#17574](https://github.com/vitessio/vitess/pull/17574) +#### VTorc + * [release-19.0] Use uint64 for binary log file position (#17472) [#17505](https://github.com/vitessio/vitess/pull/17505) +#### vttestserver + * [release-19.0] parse transaction timeout as duration (#16338) [#17406](https://github.com/vitessio/vitess/pull/17406) +### CI/Build +#### General + * [release-19.0] Bump go version to 1.22.10 [#17338](https://github.com/vitessio/vitess/pull/17338) + * [release-19.0] Upgrade the Golang version to `go1.22.11` [#17564](https://github.com/vitessio/vitess/pull/17564) +### Dependencies +#### Build/CI + * [release-19.0] Bump golang.org/x/crypto from 0.29.0 to 0.31.0 (#17376) [#17381](https://github.com/vitessio/vitess/pull/17381) +#### General + * [release-19.0] Bump golang.org/x/net from 0.25.0 to 0.33.0 (#17416) [#17420](https://github.com/vitessio/vitess/pull/17420) + * [release-19.0] CVE Fix: Update glog to v1.2.4 (#17524) [#17532](https://github.com/vitessio/vitess/pull/17532) +#### VTAdmin + * [release-19.0] Bump nanoid from 3.3.7 to 3.3.8 in /web/vtadmin (#17375) [#17377](https://github.com/vitessio/vitess/pull/17377) +### Enhancement +#### Documentation + * [release-19.0] [Direct PR] [V21 backport] CobraDocs: Remove commit hash from docs. Fix issue with workdir replacement (#17392) (#17444) [#17450](https://github.com/vitessio/vitess/pull/17450) +#### VTorc + * [release-19.0] `vtorc`: require topo for `Healthy: true` in `/debug/health` (#17129) [#17351](https://github.com/vitessio/vitess/pull/17351) +### Internal Cleanup +#### Build/CI + * [release-19.0] Security improvements to GitHub Actions (#17520) [#17528](https://github.com/vitessio/vitess/pull/17528) +### Regression +#### Query Serving + * Backport v19: Fixing Column aliases in outer join queries (#15384) [#17418](https://github.com/vitessio/vitess/pull/17418) +### Release +#### General + * [release-19.0] Bump to `v19.0.9-SNAPSHOT` after the `v19.0.8` release [#17321](https://github.com/vitessio/vitess/pull/17321) + * [release-19.0] Code Freeze for `v19.0.9` [#17587](https://github.com/vitessio/vitess/pull/17587) +### Testing +#### General + * [release-19.0] Remove broken panic handler (#17354) [#17358](https://github.com/vitessio/vitess/pull/17358) +#### VReplication + * [release-19.0] Flaky TestTickSkip: Remove inherently flaky test (#17504) [#17511](https://github.com/vitessio/vitess/pull/17511) + diff --git a/changelog/19.0/19.0.9/release_notes.md b/changelog/19.0/19.0.9/release_notes.md new file mode 100644 index 00000000000..a729b9f1ee9 --- /dev/null +++ b/changelog/19.0/19.0.9/release_notes.md @@ -0,0 +1,7 @@ +# Release of Vitess v19.0.9 +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/19.0/19.0.9/changelog.md). + +The release includes 23 merged Pull Requests. + +Thanks to all our contributors: @app/vitess-bot, @frouioui, @harshit-gangal, @mattlord, @rohit-nayak-ps, @vitess-bot + diff --git a/changelog/19.0/README.md b/changelog/19.0/README.md index 5893d3b1f4c..4d40372096f 100644 --- a/changelog/19.0/README.md +++ b/changelog/19.0/README.md @@ -1,4 +1,8 @@ ## v19.0 +* **[19.0.9](19.0.9)** + * [Changelog](19.0.9/changelog.md) + * [Release Notes](19.0.9/release_notes.md) + * **[19.0.8](19.0.8)** * [Changelog](19.0.8/changelog.md) * [Release Notes](19.0.8/release_notes.md) diff --git a/changelog/20.0/20.0.5/changelog.md b/changelog/20.0/20.0.5/changelog.md new file mode 100644 index 00000000000..ce8895f5d51 --- /dev/null +++ b/changelog/20.0/20.0.5/changelog.md @@ -0,0 +1,46 @@ +# Changelog of Vitess v20.0.5 + +### Bug fixes +#### Query Serving + * [release-20.0] Fix Data race in semi-join (#17417) [#17446](https://github.com/vitessio/vitess/pull/17446) + * [release-20.0] Reference Table DML Join Fix (#17414) [#17473](https://github.com/vitessio/vitess/pull/17473) + * [release-20.0] Fix crash in the evalengine (#17487) [#17489](https://github.com/vitessio/vitess/pull/17489) + * [release-20.0] Always return a valid timezone in cursor (#17546) [#17550](https://github.com/vitessio/vitess/pull/17550) +#### VReplication + * [release-20.0] LookupVindex: fix CLI to allow creating non-unique lookups with single column (#17301) [#17348](https://github.com/vitessio/vitess/pull/17348) + * [release-20.0] SwitchTraffic: use separate context while canceling a migration (#17340) [#17365](https://github.com/vitessio/vitess/pull/17365) + * [release-20.0] LookupVindex bug fix: Fix typos from PR 17301 (#17423) [#17437](https://github.com/vitessio/vitess/pull/17437) + * [release-20.0] Tablet picker: Handle the case where a primary tablet is not setup for a shard (#17573) [#17575](https://github.com/vitessio/vitess/pull/17575) +#### VTorc + * [release-20.0] Use uint64 for binary log file position (#17472) [#17506](https://github.com/vitessio/vitess/pull/17506) +#### vttestserver + * [release-20.0] parse transaction timeout as duration (#16338) [#17405](https://github.com/vitessio/vitess/pull/17405) +### CI/Build +#### General + * [release-20.0] Bump go version to 1.22.10 [#17337](https://github.com/vitessio/vitess/pull/17337) + * [release-20.0] Upgrade the Golang version to `go1.22.11` [#17562](https://github.com/vitessio/vitess/pull/17562) +### Dependencies +#### Build/CI + * [release-20.0] Bump golang.org/x/crypto from 0.29.0 to 0.31.0 (#17376) [#17382](https://github.com/vitessio/vitess/pull/17382) +#### General + * [release-20.0] Bump golang.org/x/net from 0.25.0 to 0.33.0 (#17416) [#17421](https://github.com/vitessio/vitess/pull/17421) + * [release-20.0] CVE Fix: Update glog to v1.2.4 (#17524) [#17533](https://github.com/vitessio/vitess/pull/17533) +#### VTAdmin + * [release-20.0] Bump nanoid from 3.3.7 to 3.3.8 in /web/vtadmin (#17375) [#17378](https://github.com/vitessio/vitess/pull/17378) +### Enhancement +#### Documentation + * [release-20.0] [Direct PR] [V21 backport] CobraDocs: Remove commit hash from docs. Fix issue with workdir replacement (#17392) (#17444) [#17451](https://github.com/vitessio/vitess/pull/17451) +#### VTorc + * [release-20.0] `vtorc`: require topo for `Healthy: true` in `/debug/health` (#17129) [#17352](https://github.com/vitessio/vitess/pull/17352) +### Internal Cleanup +#### Build/CI + * [release-20.0] Security improvements to GitHub Actions (#17520) [#17530](https://github.com/vitessio/vitess/pull/17530) +### Release +#### General + * [release-20.0] Bump to `v20.0.5-SNAPSHOT` after the `v20.0.4` release [#17323](https://github.com/vitessio/vitess/pull/17323) +### Testing +#### General + * [release-20.0] Remove broken panic handler (#17354) [#17359](https://github.com/vitessio/vitess/pull/17359) +#### VReplication + * [release-20.0] Flaky TestTickSkip: Remove inherently flaky test (#17504) [#17512](https://github.com/vitessio/vitess/pull/17512) + diff --git a/changelog/20.0/20.0.5/release_notes.md b/changelog/20.0/20.0.5/release_notes.md new file mode 100644 index 00000000000..ae00e9a6255 --- /dev/null +++ b/changelog/20.0/20.0.5/release_notes.md @@ -0,0 +1,7 @@ +# Release of Vitess v20.0.5 +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/20.0/20.0.5/changelog.md). + +The release includes 22 merged Pull Requests. + +Thanks to all our contributors: @app/vitess-bot, @frouioui, @mattlord, @vitess-bot + diff --git a/changelog/20.0/README.md b/changelog/20.0/README.md index 2fe6e3d9d61..59d34ed7173 100644 --- a/changelog/20.0/README.md +++ b/changelog/20.0/README.md @@ -1,4 +1,8 @@ ## v20.0 +* **[20.0.5](20.0.5)** + * [Changelog](20.0.5/changelog.md) + * [Release Notes](20.0.5/release_notes.md) + * **[20.0.4](20.0.4)** * [Changelog](20.0.4/changelog.md) * [Release Notes](20.0.4/release_notes.md) diff --git a/changelog/21.0/21.0.2/changelog.md b/changelog/21.0/21.0.2/changelog.md new file mode 100644 index 00000000000..4b4c45f6117 --- /dev/null +++ b/changelog/21.0/21.0.2/changelog.md @@ -0,0 +1,64 @@ +# Changelog of Vitess v21.0.2 + +### Bug fixes +#### Evalengine + * [release-21.0] Fix week number for date_format evalengine function (#17432) [#17452](https://github.com/vitessio/vitess/pull/17452) +#### Java + * [release-21.0] Use proper `groupId` for mysql connector in java (#17540) [#17541](https://github.com/vitessio/vitess/pull/17541) +#### Query Serving + * [release-21.0] Fix Data race in semi-join (#17417) [#17447](https://github.com/vitessio/vitess/pull/17447) + * [release-21.0] vexplain to protect the log fields from concurrent writes (#17460) [#17463](https://github.com/vitessio/vitess/pull/17463) + * [release-21.0] Reference Table DML Join Fix (#17414) [#17474](https://github.com/vitessio/vitess/pull/17474) + * [release-21.0] Fix crash in the evalengine (#17487) [#17490](https://github.com/vitessio/vitess/pull/17490) + * [release-21.0] Always return a valid timezone in cursor (#17546) [#17551](https://github.com/vitessio/vitess/pull/17551) + * [release-21.0] sizegen: do not ignore type aliases (#17556) [#17557](https://github.com/vitessio/vitess/pull/17557) +#### VReplication + * [release-21.0] LookupVindex: fix CLI to allow creating non-unique lookups with single column (#17301) [#17349](https://github.com/vitessio/vitess/pull/17349) + * [release-21.0] SwitchTraffic: use separate context while canceling a migration (#17340) [#17366](https://github.com/vitessio/vitess/pull/17366) + * [release-21.0] LookupVindex bug fix: Fix typos from PR 17301 (#17423) [#17438](https://github.com/vitessio/vitess/pull/17438) + * [release-21.0] Tablet picker: Handle the case where a primary tablet is not setup for a shard (#17573) [#17576](https://github.com/vitessio/vitess/pull/17576) +#### VTorc + * [release-21.0] Use uint64 for binary log file position (#17472) [#17507](https://github.com/vitessio/vitess/pull/17507) +#### schema management + * [release-21.0] schemadiff: skip keys with expressions in Online DDL analysis (#17475) [#17480](https://github.com/vitessio/vitess/pull/17480) +### CI/Build +#### Build/CI + * [release-21.0] use newer versions of actions in scorecard workflow (#17373) [#17374](https://github.com/vitessio/vitess/pull/17374) + * [release-21.0] split upgrade downgrade queries test to 2 CI workflows (#17464) [#17494](https://github.com/vitessio/vitess/pull/17494) +#### General + * [release-21.0] Bump go version to 1.23.4 [#17336](https://github.com/vitessio/vitess/pull/17336) + * [release-21.0] Upgrade the Golang version to `go1.23.5` [#17561](https://github.com/vitessio/vitess/pull/17561) +### Dependencies +#### Build/CI + * [release-21.0] Bump golang.org/x/crypto from 0.29.0 to 0.31.0 (#17376) [#17383](https://github.com/vitessio/vitess/pull/17383) +#### General + * [release-21.0] Bump golang.org/x/net from 0.29.0 to 0.33.0 (#17416) [#17422](https://github.com/vitessio/vitess/pull/17422) + * [release-21.0] CVE Fix: Update glog to v1.2.4 (#17524) [#17534](https://github.com/vitessio/vitess/pull/17534) +#### Java + * [release-21.0] [Java]: Bump mysql-connector-java version from 8.0.33 to mysql-connector-j 8.4.0 (#17522) [#17527](https://github.com/vitessio/vitess/pull/17527) +#### VTAdmin + * [release-21.0] Bump nanoid from 3.3.7 to 3.3.8 in /web/vtadmin (#17375) [#17379](https://github.com/vitessio/vitess/pull/17379) +### Enhancement +#### Documentation + * [Direct PR] [V21 backport] CobraDocs: Remove commit hash from docs. Fix issue with workdir replacement (#17392) [#17444](https://github.com/vitessio/vitess/pull/17444) +#### VTorc + * [release-21.0] `vtorc`: require topo for `Healthy: true` in `/debug/health` (#17129) [#17353](https://github.com/vitessio/vitess/pull/17353) +### Internal Cleanup +#### Build/CI + * [release-21.0] Security improvements to GitHub Actions (#17520) [#17531](https://github.com/vitessio/vitess/pull/17531) +### Regression +#### Java + * [release-21.0] [Java] Fix dependency issues in Java package (#17481) [#17484](https://github.com/vitessio/vitess/pull/17484) +### Release +#### General + * [release-21.0] Bump to `v21.0.2-SNAPSHOT` after the `v21.0.1` release [#17325](https://github.com/vitessio/vitess/pull/17325) +### Testing +#### General + * [release-21.0] Remove broken panic handler (#17354) [#17360](https://github.com/vitessio/vitess/pull/17360) +#### Query Serving + * [release-21.0] Ensure PRS runs for all the shards in `TestSemiSyncRequiredWithTwoPC` (#17384) [#17385](https://github.com/vitessio/vitess/pull/17385) +#### VReplication + * [release-21.0] Flaky test fix: TestMoveTablesSharded and TestMoveTablesUnsharded (#17343) [#17363](https://github.com/vitessio/vitess/pull/17363) + * [release-21.0] Flaky TestMoveTables(Un)sharded: Handle race condition (#17440) [#17455](https://github.com/vitessio/vitess/pull/17455) + * [release-21.0] Flaky TestTickSkip: Remove inherently flaky test (#17504) [#17513](https://github.com/vitessio/vitess/pull/17513) + diff --git a/changelog/21.0/21.0.2/release_notes.md b/changelog/21.0/21.0.2/release_notes.md new file mode 100644 index 00000000000..10c663ebff2 --- /dev/null +++ b/changelog/21.0/21.0.2/release_notes.md @@ -0,0 +1,7 @@ +# Release of Vitess v21.0.2 +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/21.0/21.0.2/changelog.md). + +The release includes 33 merged Pull Requests. + +Thanks to all our contributors: @app/vitess-bot, @dbussink, @frouioui, @rohit-nayak-ps, @vitess-bot + diff --git a/changelog/21.0/README.md b/changelog/21.0/README.md index f3a98feb55a..680a294e34b 100644 --- a/changelog/21.0/README.md +++ b/changelog/21.0/README.md @@ -1,4 +1,8 @@ ## v21.0 +* **[21.0.2](21.0.2)** + * [Changelog](21.0.2/changelog.md) + * [Release Notes](21.0.2/release_notes.md) + * **[21.0.1](21.0.1)** * [Changelog](21.0.1/changelog.md) * [Release Notes](21.0.1/release_notes.md) diff --git a/changelog/22.0/22.0.0/summary.md b/changelog/22.0/22.0.0/summary.md index d21acf48a30..f773df2b10c 100644 --- a/changelog/22.0/22.0.0/summary.md +++ b/changelog/22.0/22.0.0/summary.md @@ -3,10 +3,25 @@ ### Table of Contents - **[Major Changes](#major-changes)** + - **[Deprecations and Deletions](#deprecations-and-deletions)** + - [Deprecated VTTablet Flags](#vttablet-flags) - **[RPC Changes](#rpc-changes)** - **[Prefer not promoting a replica that is currently taking a backup](#reparents-prefer-not-backing-up)** - **[VTOrc Config File Changes](#vtorc-config-file-changes)** - + - **[VTGate Config File Changes](#vtgate-config-file-changes)** + - **[Support for More Efficient JSON Replication](#efficient-json-replication)** + - **[Support for LAST_INSERT_ID(x)](#last-insert-id)** + - **[Support for Maximum Idle Connections in the Pool](#max-idle-connections)** + - **[Stalled Disk Recovery in VTOrc](#stall-disk-recovery)** + - **[Update default MySQL version to 8.0.40](#mysql-8-0-40)** + - **[Update lite images to Debian Bookworm](#debian-bookworm)** + - **[KeyRanges in `--clusters_to_watch` in VTOrc](#key-range-vtorc)** + - **[Support for Filtering Query logs on Error](#query-logs)** +- **[Minor Changes](#minor-changes)** + - **[VTTablet Flags](#flags-vttablet)** + - **[Topology read concurrency behaviour changes](#topo-read-concurrency-changes)** + - **[VTAdmin](#vtadmin)** + - [Updated to node v22.13.1](#updated-node) ## Major Changes @@ -14,7 +29,13 @@ These are the RPC changes made in this release - -1. `GetTransactionInfo` RPC has been added to both `VtctldServer`, and `TabletManagerClient` interface. These RPCs are used to fecilitate the users in reading the state of an unresolved distributed transaction. This can be useful in debugging what went wrong and how to fix the problem. +1. `GetTransactionInfo` RPC has been added to both `VtctldServer`, and `TabletManagerClient` interface. These RPCs are used to facilitate the users in reading the state of an unresolved distributed transaction. This can be useful in debugging what went wrong and how to fix the problem. + +### Deprecations and Deletions + +#### Deprecated VTTablet Flags + +- `twopc_enable` flag is deprecated. Usage of TwoPC commit will be determined by the `transaction_mode` set on VTGate via flag or session variable. ### Prefer not promoting a replica that is currently taking a backup @@ -48,3 +69,101 @@ The following fields can be dynamically changed - 13. `change-tablets-with-errant-gtid-to-drained` To upgrade to the newer version of the configuration file, first switch to using the flags in your current deployment before upgrading. Then you can switch to using the configuration file in the newer release. + +### VTGate Config File Changes + +The Viper configuration keys for the following flags has been changed to match their flag names. Previously they had a discovery prefix instead of it being part of the name. + +| Flag Name | Old Configuration Key | New Configuration Key | +|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------| +| `discovery_low_replication_lag` | `discovery.low_replication_lag` | `discovery_low_replication_lag` | +| `discovery_high_replication_lag_minimum_serving` | `discovery.high_replication_lag_minimum_serving` | `discovery_high_replication_lag_minimum_serving` | +| `discovery_min_number_serving_vttablets` | `discovery.min_number_serving_vttablets` | `discovery_min_number_serving_vttablets` | +| `discovery_legacy_replication_lag_algorithm` | `discovery.legacy_replication_lag_algorithm` | `discovery_legacy_replication_lag_algorithm` | + +To upgrade to the newer version of the configuration keys, first switch to using the flags in your current deployment before upgrading. Then you can switch to using the new configuration keys in the newer release. + +### Support for More Efficient JSON Replication + +In [#7345](https://github.com/vitessio/vitess/pull/17345) we added support for [`--binlog-row-value-options=PARTIAL_JSON`](https://dev.mysql.com/doc/refman/en/replication-options-binary-log.html#sysvar_binlog_row_value_options). You can read more about [this feature added to MySQL 8.0 here](https://dev.mysql.com/blog-archive/efficient-json-replication-in-mysql-8-0/). + +If you are using MySQL 8.0 or later and using JSON columns, you can now enable this MySQL feature across your Vitess cluster(s) to lower the disk space needed for binary logs and improve the CPU and memory usage in both `mysqld` (standard intrashard MySQL replication) and `vttablet` ([VReplication](https://vitess.io/docs/reference/vreplication/vreplication/)) without losing any capabilities or features. + +### Support for `LAST_INSERT_ID(x)` + +In [#17408](https://github.com/vitessio/vitess/pull/17408) and [#17409](https://github.com/vitessio/vitess/pull/17409), we added the ability to use `LAST_INSERT_ID(x)` in Vitess directly at vtgate. This improvement allows certain queries—like `SELECT last_insert_id(123);` or `SELECT last_insert_id(count(*)) ...`—to be handled without relying on MySQL for the final value. + +**Limitations**: +- When using `LAST_INSERT_ID(x)` in ordered queries (e.g., `SELECT last_insert_id(col) FROM table ORDER BY foo`), MySQL sets the session’s last-insert-id value according to the *last row returned*. Vitess does not guarantee the same behavior. + +### Support for Maximum Idle Connections in the Pool + +In [#17443](https://github.com/vitessio/vitess/pull/17443) we introduced a new configurable max-idle-count parameter for connection pools. This allows you to specify the maximum number of idle connections retained in each connection pool to optimize performance and resource efficiency. + +You can control idle connection retention for the query server’s query pool, stream pool, and transaction pool with the following flags: +• --queryserver-config-query-pool-max-idle-count: Defines the maximum number of idle connections retained in the query pool. +• --queryserver-config-stream-pool-max-idle-count: Defines the maximum number of idle connections retained in the stream pool. +• --queryserver-config-txpool-max-idle-count: Defines the maximum number of idle connections retained in the transaction pool. + +This feature ensures that, during traffic spikes, idle connections are available for faster responses, while minimizing overhead in low-traffic periods by limiting the number of idle connections retained. It helps strike a balance between performance, efficiency, and cost. + +### Stalled Disk Recovery in VTOrc +VTOrc can now identify and recover from stalled disk errors. VTTablets test whether the disk is writable and they send this information in the full status output to VTOrc. If the disk is not writable on the primary tablet, VTOrc will attempt to recover the cluster by promoting a new primary. This is useful in scenarios where the disk is stalled and the primary vttablet is unable to accept writes because of it. + +To opt into this feature, `--enable-primary-disk-stalled-recovery` flag has to be specified on VTOrc, and `--disk-write-dir` flag has to be specified on the vttablets. `--disk-write-interval` and `--disk-write-timeout` flags can be used to configure the polling interval and timeout respectively. + +### Update default MySQL version to 8.0.40 + +The default major MySQL version used by our `vitess/lite:latest` image is going from `8.0.30` to `8.0.40`. +This change was brought by [Pull Request #17552](https://github.com/vitessio/vitess/pull/17552). + +VTGate also advertises MySQL version `8.0.40` by default instead of `8.0.30` if no explicit version is set. The users can set the `mysql_server_version` flag to advertise the correct version. + +#### ⚠️Upgrading to this release with vitess-operator + +If you are using the `vitess-operator`, considering that we are bumping the patch version of MySQL 80 from `8.0.30` to `8.0.40`, you will have to manually upgrade: + +1. Add `innodb_fast_shutdown=0` to your extra cnf in your YAML file. +2. Apply this file. +3. Wait for all the pods to be healthy. +4. Then change your YAML file to use the new Docker Images (`vitess/lite:v22.0.0`). +5. Remove `innodb_fast_shutdown=0` from your extra cnf in your YAML file. +6. Apply this file. + +This is the last time this will be needed in the `8.0.x` series, as starting with MySQL `8.0.35` it is possible to upgrade and downgrade between `8.0.x` versions without needing to run `innodb_fast_shutdown=0`. + +### Update lite images to Debian Bookworm + +The base system now uses Debian Bookworm instead of Debian Bullseye for the `vitess/lite` images. This change was brought by [Pull Request #17552]. + +### KeyRanges in `--clusters_to_watch` in VTOrc +VTOrc now supports specifying keyranges in the `--clusters_to_watch` flag. This means that there is no need to restart a VTOrc instance with a different flag value when you reshard a keyspace. +For example, if a VTOrc is configured to watch `ks/-80`, then it would watch all the shards that fall under the keyrange `-80`. If a reshard is performed and `-80` is split into new shards `-40` and `40-80`, the VTOrc instance will automatically start watching the new shards without needing a restart. In the previous logic, specifying `ks/-80` for the flag would mean that VTOrc would watch only 1 (or no) shard. In the new system, since we interpret `-80` as a key range, it can watch multiple shards as described in the example. +Users can continue to specify exact keyranges. The new feature is backward compatible. + +### Support for Filtering Query logs on Error + +The `querylog-mode` setting can be configured to `error` to log only queries that result in errors. This option is supported in both VTGate and VTTablet. + +## Minor Changes + +#### VTTablet Flags + +- `twopc_abandon_age` flag now supports values in the time.Duration format (e.g., 1s, 2m, 1h). +While the flag will continue to accept float values (interpreted as seconds) for backward compatibility, +**float inputs are deprecated** and will be removed in a future release. + +- `--consolidator-query-waiter-cap` flag to set the maximum number of clients allowed to wait on the consolidator. The default value is set to 0 for unlimited wait. Users can adjust this value based on the performance of VTTablet to avoid excessive memory usage and the risk of being OOMKilled, particularly in Kubernetes deployments. + +### `--topo_read_concurrency` behaviour changes + +The `--topo_read_concurrency` flag was added to all components that access the topology and the provided limit is now applied separately for each global or local cell _(default `32`)_. + +All topology read calls _(`Get`, `GetVersion`, `List` and `ListDir`)_ now respect this per-cell limit. Previous to this version a single limit was applied to all cell calls and it was not respected by many topology calls. + +### VTAdmin + +#### vtadmin-web updated to node v22.13.1 (LTS) + +Building `vtadmin-web` now requires node >= v22.13.0 (LTS). Breaking changes from v20 to v22 can be found at https://nodejs.org/en/blog/release/v22.13.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/v22.13.1. diff --git a/config/mycnf/default.cnf b/config/mycnf/default.cnf index c17165f9959..25e5398c87a 100644 --- a/config/mycnf/default.cnf +++ b/config/mycnf/default.cnf @@ -16,10 +16,6 @@ secure-file-priv = {{.SecureFilePriv}} server-id = {{.ServerID}} -# all db instances should skip starting replication threads - that way we can do any -# additional configuration (like enabling semi-sync) before we connect to -# the source. -skip_slave_start socket = {{.SocketFile}} tmpdir = {{.TmpDir}} diff --git a/config/mycnf/mariadb10.cnf b/config/mycnf/mariadb10.cnf index 120bd7b7d00..fb0becb7dcd 100644 --- a/config/mycnf/mariadb10.cnf +++ b/config/mycnf/mariadb10.cnf @@ -1,5 +1,10 @@ # This file is auto-included when MariaDB 10 is detected. +# all db instances should skip starting replication threads - that way we can do any +# additional configuration (like enabling semi-sync) before we connect to +# the source. +skip_slave_start + # Semi-sync replication is required for automated unplanned failover # (when the primary goes away). Here we just load the plugin so it's # available if desired, but it's disabled at startup. diff --git a/config/mycnf/mysql57.cnf b/config/mycnf/mysql57.cnf index 44c462749a7..485904bb2bd 100644 --- a/config/mycnf/mysql57.cnf +++ b/config/mycnf/mysql57.cnf @@ -1,5 +1,10 @@ # This file is auto-included when MySQL 5.7 is detected. +# all db instances should skip starting replication threads - that way we can do any +# additional configuration (like enabling semi-sync) before we connect to +# the source. +skip_slave_start + # MySQL 5.7 does not enable the binary log by default, and # info repositories default to file diff --git a/config/mycnf/mysql80.cnf b/config/mycnf/mysql80.cnf index 13447a7de0a..3f4297ba400 100644 --- a/config/mycnf/mysql80.cnf +++ b/config/mycnf/mysql80.cnf @@ -1,5 +1,10 @@ # This file is auto-included when MySQL 8.0 is detected. +# all db instances should skip starting replication threads - that way we can do any +# additional configuration (like enabling semi-sync) before we connect to +# the source. +skip_slave_start + # MySQL 8.0 enables binlog by default with sync_binlog and TABLE info repositories # It does not enable GTIDs or enforced GTID consistency diff --git a/config/mycnf/mysql8026.cnf b/config/mycnf/mysql8026.cnf index c7755be488f..df63a589918 100644 --- a/config/mycnf/mysql8026.cnf +++ b/config/mycnf/mysql8026.cnf @@ -1,5 +1,10 @@ # This file is auto-included when MySQL 8.0.26 or later is detected. +# all db instances should skip starting replication threads - that way we can do any +# additional configuration (like enabling semi-sync) before we connect to +# the source. +skip_replica_start + # MySQL 8.0 enables binlog by default with sync_binlog and TABLE info repositories # It does not enable GTIDs or enforced GTID consistency diff --git a/config/mycnf/mysql84.cnf b/config/mycnf/mysql84.cnf index 93e4bd571e1..e75c885af39 100644 --- a/config/mycnf/mysql84.cnf +++ b/config/mycnf/mysql84.cnf @@ -1,5 +1,10 @@ # This file is auto-included when MySQL 8.4.0 or later is detected. +# all db instances should skip starting replication threads - that way we can do any +# additional configuration (like enabling semi-sync) before we connect to +# the source. +skip_replica_start + # MySQL 8.0 enables binlog by default with sync_binlog and TABLE info repositories # It does not enable GTIDs or enforced GTID consistency diff --git a/config/mycnf/sbr.cnf b/config/mycnf/sbr.cnf deleted file mode 100644 index 5808e0430f3..00000000000 --- a/config/mycnf/sbr.cnf +++ /dev/null @@ -1,3 +0,0 @@ -# This file is used to allow legacy tests to pass -# In theory it should not be required -binlog_format=statement diff --git a/doc/internal/release/how-to-release.md b/doc/internal/release/how-to-release.md index 08411f9c0ac..97e58a074d7 100644 --- a/doc/internal/release/how-to-release.md +++ b/doc/internal/release/how-to-release.md @@ -364,7 +364,8 @@ You will need administrator privileges on the vitess repository to be able to ma ```bash cd ./java/ - mvn clean deploy -P release -DskipTests + # For <= v21.0, we must use -DskipTests in the mvn command below + mvn clean deploy -P release cd .. ``` diff --git a/docker/binaries/vtadmin/Dockerfile b/docker/binaries/vtadmin/Dockerfile index fe69237ea13..c51527c1f39 100644 --- a/docker/binaries/vtadmin/Dockerfile +++ b/docker/binaries/vtadmin/Dockerfile @@ -13,11 +13,11 @@ # limitations under the License. ARG VT_BASE_VER=latest -ARG DEBIAN_VER=bullseye-slim +ARG DEBIAN_VER=bookworm-slim FROM vitess/lite:${VT_BASE_VER} AS lite -FROM node:20-${DEBIAN_VER} as node +FROM node:22-${DEBIAN_VER} as node # Prepare directory structure. RUN mkdir -p /vt/web diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index b52783d0c30..9728dffbab8 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -153,4 +153,13 @@ List of changes between bootstrap image versions. ## [39] - 2024-12-04 ### Changes -- Update build to golang 1.23.4 \ No newline at end of file +- Update build to golang 1.23.4 + +## [40] - 2025-01-17 +### Changes +- Update build to golang 1.23.5 + +## [41] - 2025-01-15 +### Changes +- Update base image to bookworm +- Add MySQL84 image \ No newline at end of file diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 3ace19543f1..e0866fe4bda 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.23.4-bullseye +FROM --platform=linux/amd64 golang:1.23.5-bookworm # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ @@ -8,12 +8,13 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins chromium \ curl \ default-jdk \ - etcd \ + etcd-client \ + etcd-server \ g++ \ git \ + gnupg \ make \ maven \ - software-properties-common \ unzip \ zip \ xvfb \ diff --git a/docker/bootstrap/Dockerfile.mysql80 b/docker/bootstrap/Dockerfile.mysql80 index b4fec6b7d11..e8ca365a704 100644 --- a/docker/bootstrap/Dockerfile.mysql80 +++ b/docker/bootstrap/Dockerfile.mysql80 @@ -8,9 +8,9 @@ USER root # Install MySQL 8.0 RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver keyserver.ubuntu.com 8C718D3B5072E1F5 && break; done && \ for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver keyserver.ubuntu.com A8D3785C && break; done && \ - add-apt-repository 'deb http://repo.mysql.com/apt/debian/ bullseye mysql-8.0' && \ + echo 'deb http://repo.mysql.com/apt/debian/ bookworm mysql-8.0' > /etc/apt/sources.list.d/mysql.list && \ for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keyserver.ubuntu.com --recv-keys 9334A25F8507EFA5 && break; done && \ - echo 'deb http://repo.percona.com/apt bullseye main' > /etc/apt/sources.list.d/percona.list && \ + echo 'deb http://repo.percona.com/apt bookworm main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.mysql84 b/docker/bootstrap/Dockerfile.mysql84 new file mode 100644 index 00000000000..2f90d588701 --- /dev/null +++ b/docker/bootstrap/Dockerfile.mysql84 @@ -0,0 +1,23 @@ +ARG bootstrap_version +ARG image="vitess/bootstrap:${bootstrap_version}-common" + +FROM --platform=linux/amd64 "${image}" + +USER root + +# Install MySQL 8.4 +RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver keyserver.ubuntu.com 8C718D3B5072E1F5 && break; done && \ + for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver keyserver.ubuntu.com A8D3785C && break; done && \ + echo 'deb http://repo.mysql.com/apt/debian/ bookworm mysql-8.4-lts' > /etc/apt/sources.list.d/mysql.list && \ + for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keyserver.ubuntu.com --recv-keys 9334A25F8507EFA5 && break; done && \ + echo 'deb http://repo.percona.com/pxb-84-lts/apt bookworm main' > /etc/apt/sources.list.d/percona.list && \ + { \ + echo debconf debconf/frontend select Noninteractive; \ + echo percona-server-server-8.4 percona-server-server/root_password password 'unused'; \ + echo percona-server-server-8.4 percona-server-server/root_password_again password 'unused'; \ + } | debconf-set-selections && \ + apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server libmysqlclient-dev libdbd-mysql-perl rsync libev4 libcurl4-openssl-dev percona-xtrabackup-84 && \ + rm -rf /var/lib/apt/lists/* + +USER vitess diff --git a/docker/bootstrap/Dockerfile.percona80 b/docker/bootstrap/Dockerfile.percona80 index 147b988b002..53b16a8eb4b 100644 --- a/docker/bootstrap/Dockerfile.percona80 +++ b/docker/bootstrap/Dockerfile.percona80 @@ -7,7 +7,7 @@ USER root # Install Percona 8.0 RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keyserver.ubuntu.com --recv-keys 9334A25F8507EFA5 && break; done \ - && echo 'deb http://repo.percona.com/ps-80/apt bullseye main' > /etc/apt/sources.list.d/percona.list && \ + && echo 'deb http://repo.percona.com/ps-80/apt bookworm main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ @@ -23,7 +23,7 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keyserver.ubuntu.c rsync \ libev4 \ # && rm -f /etc/apt/sources.list.d/percona.list \ - && echo 'deb http://repo.percona.com/apt bullseye main' > /etc/apt/sources.list.d/percona.list \ + && echo 'deb http://repo.percona.com/apt bookworm main' > /etc/apt/sources.list.d/percona.list \ # { \ # echo debconf debconf/frontend select Noninteractive; \ # echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/README.md b/docker/bootstrap/README.md index b273305d6b9..7e0f9667e3f 100644 --- a/docker/bootstrap/README.md +++ b/docker/bootstrap/README.md @@ -7,6 +7,7 @@ The `vitess/bootstrap` image comes in different flavors: * `vitess/bootstrap:common` - dependencies that are common to all flavors * `vitess/bootstrap:mysql80` - bootstrap image for MySQL 8.0 +* `vitess/bootstrap:mysql84` - bootstrap image for MySQL 8.4 * `vitess/bootstrap:percona80` - bootstrap image for Percona Server 8.0 **NOTE: Unlike the base image that builds Vitess itself, this bootstrap image diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index fff1414fab6..c75a0a5ad4c 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.23.4-bullseye AS builder +FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER @@ -31,7 +31,7 @@ COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM --platform=linux/amd64 debian:bullseye-slim +FROM --platform=linux/amd64 debian:bookworm-slim # Install locale required for mysqlsh RUN apt-get update && apt-get install -y locales \ diff --git a/docker/lite/Dockerfile.mysql84 b/docker/lite/Dockerfile.mysql84 new file mode 100644 index 00000000000..e2836ca3047 --- /dev/null +++ b/docker/lite/Dockerfile.mysql84 @@ -0,0 +1,63 @@ +# Copyright 2025 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. + +FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder + +# Allows docker builds to set the BUILD_NUMBER +ARG BUILD_NUMBER + +WORKDIR /vt/src/vitess.io/vitess + +# Create vitess user +RUN groupadd -r vitess && useradd -r -g vitess vitess +RUN mkdir -p /vt/vtdataroot /home/vitess +RUN chown -R vitess:vitess /vt /home/vitess +USER vitess + +# Re-copy sources from working tree. +COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess + +RUN make install PREFIX=/vt/install + +# Start over and build the final image. +FROM --platform=linux/amd64 debian:bookworm-slim + +# Install locale required for mysqlsh +RUN apt-get update && apt-get install -y locales \ + && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \ + && locale-gen en_US.UTF-8 + +# Install dependencies +COPY docker/utils/install_dependencies.sh /vt/dist/install_dependencies.sh +RUN /vt/dist/install_dependencies.sh mysql84 + +# Set up Vitess user and directory tree. +RUN groupadd -r vitess && useradd -r -g vitess vitess +RUN mkdir -p /vt/vtdataroot /home/vitess && chown -R vitess:vitess /vt /home/vitess + +# Set up Vitess environment (just enough to run pre-built Go binaries) +ENV VTROOT /vt +ENV VTDATAROOT /vt/vtdataroot +ENV PATH $VTROOT/bin:$PATH + +# Copy artifacts from builder layer. +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=builder --chown=vitess:vitess /vt/install /vt +COPY --from=builder --chown=vitess:vitess /vt/src/vitess.io/vitess/web/vtadmin /vt/web/vtadmin +COPY --from=builder --chown=vitess:vitess /vt/src/vitess.io/vitess/config/init_db.sql /vt/config/ +COPY --from=builder --chown=vitess:vitess /vt/src/vitess.io/vitess/config/mycnf /vt/config/ + +# Create mount point for actual data (e.g. MySQL data dir) +VOLUME /vt/vtdataroot +USER vitess diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index a839fb35514..16e1da78627 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.23.4-bullseye AS builder +FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER @@ -31,7 +31,7 @@ COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM --platform=linux/amd64 debian:bullseye-slim +FROM --platform=linux/amd64 debian:bookworm-slim # Install dependencies COPY docker/utils/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/utils/install_dependencies.sh b/docker/utils/install_dependencies.sh index 91e6e2b8c76..59e16b6303a 100755 --- a/docker/utils/install_dependencies.sh +++ b/docker/utils/install_dependencies.sh @@ -71,64 +71,58 @@ apt-get install -y --no-install-recommends "${BASE_PACKAGES[@]}" # Packages specific to certain flavors. case "${FLAVOR}" in -mysql57) +mysql80) if [ -z "$VERSION" ]; then - VERSION=5.7.31 + VERSION=8.0.40 fi - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/libmysqlclient20_${VERSION}-1debian10_amd64.deb /tmp/libmysqlclient20_${VERSION}-1debian10_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-community-client_${VERSION}-1debian10_amd64.deb /tmp/mysql-community-client_${VERSION}-1debian10_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-client_${VERSION}-1debian10_amd64.deb /tmp/mysql-client_${VERSION}-1debian10_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-community-server_${VERSION}-1debian10_amd64.deb /tmp/mysql-community-server_${VERSION}-1debian10_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-server_${VERSION}-1debian10_amd64.deb /tmp/mysql-server_${VERSION}-1debian10_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-common_${VERSION}-1debian12_amd64.deb /tmp/mysql-common_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/libmysqlclient21_${VERSION}-1debian12_amd64.deb /tmp/libmysqlclient21_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-client_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-server_${VERSION}-1debian12_amd64.deb PACKAGES=( - /tmp/libmysqlclient20_${VERSION}-1debian10_amd64.deb - /tmp/mysql-community-client_${VERSION}-1debian10_amd64.deb - /tmp/mysql-client_${VERSION}-1debian10_amd64.deb - /tmp/mysql-community-server_${VERSION}-1debian10_amd64.deb - /tmp/mysql-server_${VERSION}-1debian10_amd64.deb + /tmp/mysql-common_${VERSION}-1debian12_amd64.deb + /tmp/libmysqlclient21_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb + /tmp/mysql-client_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb + /tmp/mysql-server_${VERSION}-1debian12_amd64.deb mysql-shell - percona-xtrabackup-24 + percona-xtrabackup-80 ) ;; -mysql80) +mysql84) if [ -z "$VERSION" ]; then - VERSION=8.0.30 + VERSION=8.4.3 fi - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-common_${VERSION}-1debian11_amd64.deb /tmp/mysql-common_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/libmysqlclient21_${VERSION}-1debian11_amd64.deb /tmp/libmysqlclient21_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-core_${VERSION}-1debian11_amd64.deb /tmp/mysql-community-client-core_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-plugins_${VERSION}-1debian11_amd64.deb /tmp/mysql-community-client-plugins_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client_${VERSION}-1debian11_amd64.deb /tmp/mysql-community-client_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-client_${VERSION}-1debian11_amd64.deb /tmp/mysql-client_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server-core_${VERSION}-1debian11_amd64.deb /tmp/mysql-community-server-core_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server_${VERSION}-1debian11_amd64.deb /tmp/mysql-community-server_${VERSION}-1debian11_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-server_${VERSION}-1debian11_amd64.deb /tmp/mysql-server_${VERSION}-1debian11_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-common_${VERSION}-1debian12_amd64.deb /tmp/mysql-common_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/libmysqlclient24_${VERSION}-1debian12_amd64.deb /tmp/libmysqlclient24_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-client_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-server-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb + do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-server_${VERSION}-1debian12_amd64.deb PACKAGES=( - /tmp/mysql-common_${VERSION}-1debian11_amd64.deb - /tmp/libmysqlclient21_${VERSION}-1debian11_amd64.deb - /tmp/mysql-community-client-core_${VERSION}-1debian11_amd64.deb - /tmp/mysql-community-client-plugins_${VERSION}-1debian11_amd64.deb - /tmp/mysql-community-client_${VERSION}-1debian11_amd64.deb - /tmp/mysql-client_${VERSION}-1debian11_amd64.deb - /tmp/mysql-community-server-core_${VERSION}-1debian11_amd64.deb - /tmp/mysql-community-server_${VERSION}-1debian11_amd64.deb - /tmp/mysql-server_${VERSION}-1debian11_amd64.deb + /tmp/mysql-common_${VERSION}-1debian12_amd64.deb + /tmp/libmysqlclient24_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb + /tmp/mysql-client_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb + /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb + /tmp/mysql-server_${VERSION}-1debian12_amd64.deb mysql-shell - percona-xtrabackup-80 - ) - ;; -percona) - PACKAGES=( - libcurl3 - percona-server-server-5.6 - percona-xtrabackup - ) - ;; -percona57) - PACKAGES=( - libperconaserverclient20 - percona-server-server-5.7 - percona-xtrabackup-24 + percona-xtrabackup-84 ) ;; percona80) @@ -155,39 +149,30 @@ add_apt_key 9334A25F8507EFA5 # Add extra apt repositories for MySQL. case "${FLAVOR}" in -mysql57) - echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-5.7' > /etc/apt/sources.list.d/mysql.list - ;; mysql80) - echo 'deb http://repo.mysql.com/apt/debian/ bullseye mysql-8.0' > /etc/apt/sources.list.d/mysql.list + echo 'deb http://repo.mysql.com/apt/debian/ bookworm mysql-8.0' > /etc/apt/sources.list.d/mysql.list + ;; +mysql84) + echo 'deb http://repo.mysql.com/apt/debian/ bookworm mysql-8.4-lts' > /etc/apt/sources.list.d/mysql.list ;; esac # Add extra apt repositories for Percona Server and/or Percona XtraBackup. case "${FLAVOR}" in -mysql57) - echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list +mysql80) + echo 'deb http://repo.percona.com/apt bookworm main' > /etc/apt/sources.list.d/percona.list ;; -mysql80|percona57) - echo 'deb http://repo.percona.com/apt bullseye main' > /etc/apt/sources.list.d/percona.list +mysql84) + echo 'deb http://repo.percona.com/pxb-84-lts/apt bookworm main' > /etc/apt/sources.list.d/percona.list ;; percona80) - echo 'deb http://repo.percona.com/apt bullseye main' > /etc/apt/sources.list.d/percona.list - echo 'deb http://repo.percona.com/ps-80/apt bullseye main' > /etc/apt/sources.list.d/percona80.list + echo 'deb http://repo.percona.com/apt bookworm main' > /etc/apt/sources.list.d/percona.list + echo 'deb http://repo.percona.com/ps-80/apt bookworm main' > /etc/apt/sources.list.d/percona80.list ;; esac # Pre-fill values for installation prompts that are normally interactive. case "${FLAVOR}" in -percona57) - debconf-set-selections < 0: // Command (top-level or not) with children. @@ -151,7 +150,6 @@ func restructure(rootDir string, dir string, name string, commands []*cobra.Comm oldName := filepath.Join(rootDir, fullCmdFilename+".md") newName := filepath.Join(dir, fullCmdFilename+".md") - if err := os.Rename(oldName, newName); err != nil { return fmt.Errorf("failed to move child command %s to its parent's dir: %w", fullCmdFilename, err) } @@ -166,6 +164,14 @@ func restructure(rootDir string, dir string, name string, commands []*cobra.Comm } default: // Top-level command without children. Nothing to restructure. + // However we still need to anonymize the homedir in the help text. + if cmd.Name() == "help" { + // all commands with children have their own "help" subcommand, + // which we do not generate docs for + continue + } + f := filepath.Join(dir, fullCmdFilename+".md") + _ = anonymizeHomedir(f) // it is possible that the file does not exist, so we ignore the error continue } } @@ -190,11 +196,14 @@ func anonymizeHomedir(file string) (err error) { if err != nil { return err } + if _, err := os.Stat(file); err != nil { + return nil + } // We're replacing the stuff inside the square brackets in the example sed // below: // 's:Paths to search for config files in. (default \[.*\])$:Paths to search for config files in. (default \[\]):' - sed := exec.Command("sed", "-i", "-e", fmt.Sprintf("s:%s::i", wd), file) + sed := exec.Command("sed", "-i", "", "-e", fmt.Sprintf("s:%s:%s:", wd, ""), file) if out, err := sed.CombinedOutput(); err != nil { return fmt.Errorf("%w: %s", err, out) } @@ -224,7 +233,6 @@ func getCommitID(ref string) (string, error) { const frontmatter = `--- title: %s series: %s -commit: %s --- ` @@ -240,7 +248,7 @@ func frontmatterFilePrepender(sha string) func(filename string) string { cmdName = strings.ReplaceAll(cmdName, "_", " ") - return fmt.Sprintf(frontmatter, cmdName, root, sha) + return fmt.Sprintf(frontmatter, cmdName, root) } } diff --git a/go/cmd/internal/docgen/docgen_test.go b/go/cmd/internal/docgen/docgen_test.go index 2370727cde5..741f5ecc577 100644 --- a/go/cmd/internal/docgen/docgen_test.go +++ b/go/cmd/internal/docgen/docgen_test.go @@ -41,7 +41,7 @@ func TestGenerateMarkdownTree(t *testing.T) { name: "current dir", dir: "./", cmd: &cobra.Command{}, - expectErr: false, + expectErr: true, }, { name: "Permission denied", diff --git a/go/cmd/vtbackup/cli/vtbackup.go b/go/cmd/vtbackup/cli/vtbackup.go index 1b61c886ae7..5306cc21f11 100644 --- a/go/cmd/vtbackup/cli/vtbackup.go +++ b/go/cmd/vtbackup/cli/vtbackup.go @@ -19,6 +19,7 @@ package cli import ( "context" "crypto/rand" + "errors" "fmt" "math" "math/big" @@ -65,6 +66,8 @@ const ( phaseNameTakeNewBackup = "TakeNewBackup" phaseStatusCatchupReplicationStalled = "Stalled" phaseStatusCatchupReplicationStopped = "Stopped" + + timeoutWaitingForReplicationStatus = 60 * time.Second ) var ( @@ -335,6 +338,18 @@ func takeBackup(ctx, backgroundCtx context.Context, topoServer *topo.Server, bac if err != nil { return fmt.Errorf("failed to initialize mysql config: %v", err) } + ctx, cancelCtx := context.WithCancel(ctx) + backgroundCtx, cancelBackgroundCtx := context.WithCancel(backgroundCtx) + defer func() { + cancelCtx() + cancelBackgroundCtx() + }() + mysqld.OnTerm(func() { + log.Warning("Cancelling vtbackup as MySQL has terminated") + cancelCtx() + cancelBackgroundCtx() + }) + initCtx, initCancel := context.WithTimeout(ctx, mysqlTimeout) defer initCancel() initMysqldAt := time.Now() @@ -520,7 +535,13 @@ func takeBackup(ctx, backgroundCtx context.Context, topoServer *topo.Server, bac waitStartTime = time.Now() ) + + lastErr := vterrors.NewLastError("replication catch up", timeoutWaitingForReplicationStatus) for { + if !lastErr.ShouldRetry() { + return fmt.Errorf("timeout waiting for replication status after %.0f seconds", timeoutWaitingForReplicationStatus.Seconds()) + } + select { case <-ctx.Done(): return fmt.Errorf("error in replication catch up: %v", ctx.Err()) @@ -530,6 +551,7 @@ func takeBackup(ctx, backgroundCtx context.Context, topoServer *topo.Server, bac lastStatus = status status, statusErr = mysqld.ReplicationStatus(ctx) if statusErr != nil { + lastErr.Record(statusErr) log.Warningf("Error getting replication status: %v", statusErr) continue } @@ -548,7 +570,10 @@ func takeBackup(ctx, backgroundCtx context.Context, topoServer *topo.Server, bac } } if !status.Healthy() { - log.Warning("Replication has stopped before backup could be taken. Trying to restart replication.") + errStr := "Replication has stopped before backup could be taken. Trying to restart replication." + log.Warning(errStr) + lastErr.Record(errors.New(strings.ToLower(errStr))) + phaseStatus.Set([]string{phaseNameCatchupReplication, phaseStatusCatchupReplicationStopped}, 1) if err := startReplication(ctx, mysqld, topoServer); err != nil { log.Warningf("Failed to restart replication: %v", err) diff --git a/go/cmd/vtcombo/cli/vschema_watcher.go b/go/cmd/vtcombo/cli/vschema_watcher.go index 484c7736424..7f6adad3c22 100644 --- a/go/cmd/vtcombo/cli/vschema_watcher.go +++ b/go/cmd/vtcombo/cli/vschema_watcher.go @@ -56,17 +56,20 @@ func loadKeyspacesFromDir(ctx context.Context, dir string, ts *topo.Server) { log.Fatalf("Unable to read keyspace file %v: %v", ksFile, err) } - keyspace := &vschemapb.Keyspace{} - err = json.Unmarshal(jsonData, keyspace) + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: ks.Name, + Keyspace: &vschemapb.Keyspace{}, + } + err = json.Unmarshal(jsonData, ksvs.Keyspace) if err != nil { log.Fatalf("Unable to parse keyspace file %v: %v", ksFile, err) } - _, err = vindexes.BuildKeyspace(keyspace, env.Parser()) + _, err = vindexes.BuildKeyspace(ksvs.Keyspace, env.Parser()) if err != nil { log.Fatalf("Invalid keyspace definition: %v", err) } - ts.SaveVSchema(ctx, ks.Name, keyspace) + ts.SaveVSchema(ctx, ksvs) log.Infof("Loaded keyspace %v from %v\n", ks.Name, ksFile) } } diff --git a/go/cmd/vtctldclient/command/framework_test.go b/go/cmd/vtctldclient/command/framework_test.go new file mode 100644 index 00000000000..3e4a6753411 --- /dev/null +++ b/go/cmd/vtctldclient/command/framework_test.go @@ -0,0 +1,267 @@ +/* +Copyright 2025 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 command + +import ( + "context" + "net" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/dbconfigs" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtenv" + "vitess.io/vitess/go/vt/vttablet/grpctmserver" + "vitess.io/vitess/go/vt/vttablet/tabletconntest" + "vitess.io/vitess/go/vt/vttablet/tabletmanager" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" + "vitess.io/vitess/go/vt/vttablet/tabletservermock" + "vitess.io/vitess/go/vt/vttablet/tmclient" + + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + + // Import the gRPC client implementation for tablet manager. + _ "vitess.io/vitess/go/vt/vttablet/grpctmclient" + + // Import the gRPC client implementation for query service. + _ "vitess.io/vitess/go/vt/vttablet/grpctabletconn" +) + +func init() { + tabletconntest.SetProtocol("go.cmd.vtctldclient.command", "grpc") +} + +// This file contains utility methods for unit tests. +// We allow the creation of fake tablets, and running their event loop based +// on a FakeMysqlDaemon. + +// FakeTablet keeps track of a fake tablet in memory. It has: +// - a Tablet record (used for creating the tablet, kept for user's information) +// - a FakeMysqlDaemon (used by the fake event loop) +// - a 'done' channel (used to terminate the fake event loop) +type FakeTablet struct { + // Tablet and FakeMysqlDaemon are populated at NewFakeTablet time. + // We also create the RPCServer, so users can register more services + // before calling StartActionLoop(). + Tablet *topodatapb.Tablet + FakeMysqlDaemon *mysqlctl.FakeMysqlDaemon + RPCServer *grpc.Server + + // The following fields are created when we start the event loop for + // the tablet, and closed / cleared when we stop it. + // The Listener is used by the gRPC server. + TM *tabletmanager.TabletManager + Listener net.Listener + + // These optional fields are used if the tablet also needs to + // listen on the 'vt' port. + StartHTTPServer bool + HTTPListener net.Listener + HTTPServer *http.Server +} + +// TabletOption is an interface for changing tablet parameters. +// It's a way to pass multiple parameters to NewFakeTablet without +// making it too cumbersome. +type TabletOption func(tablet *topodatapb.Tablet) + +// TabletKeyspaceShard is the option to set the tablet keyspace and shard +func TabletKeyspaceShard(t *testing.T, keyspace, shard string) TabletOption { + return func(tablet *topodatapb.Tablet) { + tablet.Keyspace = keyspace + shard, kr, err := topo.ValidateShardName(shard) + if err != nil { + require.FailNow(t, "cannot ValidateShardName value %v", shard) + } + tablet.Shard = shard + tablet.KeyRange = kr + } +} + +// ForceInitTablet is the tablet option to set the 'force' flag during InitTablet +func ForceInitTablet() TabletOption { + return func(tablet *topodatapb.Tablet) { + // set the force_init field into the portmap as a hack + tablet.PortMap["force_init"] = 1 + } +} + +// StartHTTPServer is the tablet option to start the HTTP server when +// starting a tablet. +func StartHTTPServer() TabletOption { + return func(tablet *topodatapb.Tablet) { + // set the start_http_server field into the portmap as a hack + tablet.PortMap["start_http_server"] = 1 + } +} + +// NewFakeTablet creates the test tablet in the topology. 'uid' +// has to be between 0 and 99. All the tablet info will be derived +// from that. Look at the implementation if you need values. +// Use TabletOption implementations if you need to change values at creation. +// 'db' can be nil if the test doesn't use a database at all. +func NewFakeTablet(t *testing.T, ts *topo.Server, cell string, uid uint32, tabletType topodatapb.TabletType, db *fakesqldb.DB, options ...TabletOption) *FakeTablet { + t.Helper() + + if uid > 99 { + require.FailNow(t, "uid has to be between 0 and 99: %v", uid) + } + mysqlPort := int32(3300 + uid) + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{Cell: cell, Uid: uid}, + Hostname: "127.0.0.1", + MysqlHostname: "127.0.0.1", + PortMap: map[string]int32{ + "vt": int32(8100 + uid), + "grpc": int32(8200 + uid), + }, + Keyspace: "test_keyspace", + Shard: "0", + Type: tabletType, + } + tablet.MysqlPort = mysqlPort + for _, option := range options { + option(tablet) + } + _, startHTTPServer := tablet.PortMap["start_http_server"] + delete(tablet.PortMap, "start_http_server") + _, force := tablet.PortMap["force_init"] + delete(tablet.PortMap, "force_init") + if err := ts.InitTablet(context.Background(), tablet, force, true /* createShardAndKeyspace */, false /* allowUpdate */); err != nil { + require.FailNow(t, "cannot create tablet %v: %v", uid, err) + } + + // create a FakeMysqlDaemon with the right information by default. + fakeMysqlDaemon := mysqlctl.NewFakeMysqlDaemon(db) + fakeMysqlDaemon.MysqlPort.Store(mysqlPort) + + return &FakeTablet{ + Tablet: tablet, + FakeMysqlDaemon: fakeMysqlDaemon, + RPCServer: grpc.NewServer(), + StartHTTPServer: startHTTPServer, + } +} + +// StartActionLoop will start the action loop for a fake tablet, +// using ft.FakeMysqlDaemon as the backing mysqld. +func (ft *FakeTablet) StartActionLoop(t *testing.T, ts *topo.Server) { + t.Helper() + if ft.TM != nil { + require.FailNow(t, "TM for %v is already running", ft.Tablet.Alias) + } + + // Listen on a random port for gRPC. + var err error + ft.Listener, err = net.Listen("tcp", "127.0.0.1:0") + if err != nil { + require.FailNow(t, "Cannot listen: %v", err) + } + gRPCPort := int32(ft.Listener.Addr().(*net.TCPAddr).Port) + + // If needed, listen on a random port for HTTP. + vtPort := ft.Tablet.PortMap["vt"] + if ft.StartHTTPServer { + ft.HTTPListener, err = net.Listen("tcp", "127.0.0.1:0") + if err != nil { + require.FailNow(t, "Cannot listen on http port: %v", err) + } + handler := http.NewServeMux() + ft.HTTPServer = &http.Server{ + Handler: handler, + } + go func() { + _ = ft.HTTPServer.Serve(ft.HTTPListener) + }() + vtPort = int32(ft.HTTPListener.Addr().(*net.TCPAddr).Port) + } + ft.Tablet.PortMap["vt"] = vtPort + ft.Tablet.PortMap["grpc"] = gRPCPort + ft.Tablet.Hostname = "127.0.0.1" + + // Create a test tm on that port, and re-read the record + // (it has new ports and IP). + ft.TM = &tabletmanager.TabletManager{ + BatchCtx: context.Background(), + TopoServer: ts, + MysqlDaemon: ft.FakeMysqlDaemon, + DBConfigs: &dbconfigs.DBConfigs{}, + QueryServiceControl: tabletservermock.NewController(), + VREngine: vreplication.NewTestEngine(ts, ft.Tablet.Alias.Cell, ft.FakeMysqlDaemon, binlogplayer.NewFakeDBClient, binlogplayer.NewFakeDBClient, topoproto.TabletDbName(ft.Tablet), nil), + Env: vtenv.NewTestEnv(), + } + if err := ft.TM.Start(ft.Tablet, nil); err != nil { + require.FailNow(t, "Error in tablet - %v, err - %v", topoproto.TabletAliasString(ft.Tablet.Alias), err.Error()) + } + ft.Tablet = ft.TM.Tablet() + + // Register the gRPC server, and starts listening. + grpctmserver.RegisterForTest(ft.RPCServer, ft.TM) + go ft.RPCServer.Serve(ft.Listener) + + // And wait for it to serve, so we don't start using it before it's + // ready. + timeout := 5 * time.Second + step := 10 * time.Millisecond + c := tmclient.NewTabletManagerClient() + for timeout >= 0 { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + err := c.Ping(ctx, ft.TM.Tablet()) + cancel() + if err == nil { + break + } + time.Sleep(step) + timeout -= step + } + if timeout < 0 { + panic("StartActionLoop failed.") + } +} + +// StopActionLoop will stop the Action Loop for the given FakeTablet +func (ft *FakeTablet) StopActionLoop(t *testing.T) { + if ft.TM == nil { + return + } + if ft.StartHTTPServer { + ft.HTTPListener.Close() + } + ft.Listener.Close() + ft.TM.Stop() + ft.TM = nil + ft.Listener = nil + ft.HTTPListener = nil +} + +// Target returns the keyspace/shard/type info of this tablet as Target. +func (ft *FakeTablet) Target() *querypb.Target { + return &querypb.Target{ + Keyspace: ft.Tablet.Keyspace, + Shard: ft.Tablet.Shard, + TabletType: ft.Tablet.Type, + } +} diff --git a/go/cmd/vtctldclient/command/keyspaces.go b/go/cmd/vtctldclient/command/keyspaces.go index 565e0c8aa82..7eb9494a9c9 100644 --- a/go/cmd/vtctldclient/command/keyspaces.go +++ b/go/cmd/vtctldclient/command/keyspaces.go @@ -26,6 +26,7 @@ import ( "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/protoutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/cmd/vtctldclient/cli" "vitess.io/vitess/go/constants/sidecar" @@ -109,19 +110,10 @@ SetKeyspaceDurabilityPolicy --durability-policy='semi_sync' customer`, Args: cobra.ExactArgs(1), RunE: commandSetKeyspaceDurabilityPolicy, } - // ValidateSchemaKeyspace makes a ValidateSchemaKeyspace gRPC call to a vtctld. - ValidateSchemaKeyspace = &cobra.Command{ - Use: "ValidateSchemaKeyspace [--exclude-tables=] [--include-views] [--skip-no-primary] [--include-vschema] ", - Short: "Validates that the schema on the primary tablet for shard 0 matches the schema on all other tablets in the keyspace.", - DisableFlagsInUseLine: true, - Aliases: []string{"validateschemakeyspace"}, - Args: cobra.ExactArgs(1), - RunE: commandValidateSchemaKeyspace, - } // ValidateVersionKeyspace makes a ValidateVersionKeyspace gRPC call to a vtctld. ValidateVersionKeyspace = &cobra.Command{ Use: "ValidateVersionKeyspace ", - Short: "Validates that the version on the primary tablet of shard 0 matches all of the other tablets in the keyspace.", + Short: "Validates that the version on the primary tablet of the first shard matches all of the other tablets in the keyspace.", DisableFlagsInUseLine: true, Aliases: []string{"validateversionkeyspace"}, Args: cobra.ExactArgs(1), @@ -153,7 +145,7 @@ func commandCreateKeyspace(cmd *cobra.Command, args []string) error { var snapshotTime *vttime.Time if topodatapb.KeyspaceType(createKeyspaceOptions.KeyspaceType) == topodatapb.KeyspaceType_SNAPSHOT { - if createKeyspaceOptions.DurabilityPolicy != "none" { + if createKeyspaceOptions.DurabilityPolicy != policy.DurabilityNone { return errors.New("--durability-policy cannot be specified while creating a snapshot keyspace") } @@ -350,38 +342,6 @@ func commandSetKeyspaceDurabilityPolicy(cmd *cobra.Command, args []string) error return nil } -var validateSchemaKeyspaceOptions = struct { - ExcludeTables []string - IncludeViews bool - SkipNoPrimary bool - IncludeVSchema bool -}{} - -func commandValidateSchemaKeyspace(cmd *cobra.Command, args []string) error { - cli.FinishedParsing(cmd) - - ks := cmd.Flags().Arg(0) - resp, err := client.ValidateSchemaKeyspace(commandCtx, &vtctldatapb.ValidateSchemaKeyspaceRequest{ - Keyspace: ks, - ExcludeTables: validateSchemaKeyspaceOptions.ExcludeTables, - IncludeVschema: validateSchemaKeyspaceOptions.IncludeVSchema, - SkipNoPrimary: validateSchemaKeyspaceOptions.SkipNoPrimary, - IncludeViews: validateSchemaKeyspaceOptions.IncludeViews, - }) - - if err != nil { - return err - } - - data, err := cli.MarshalJSON(resp) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - return nil -} - func commandValidateVersionKeyspace(cmd *cobra.Command, args []string) error { cli.FinishedParsing(cmd) @@ -409,7 +369,7 @@ func init() { CreateKeyspace.Flags().Var(&createKeyspaceOptions.KeyspaceType, "type", "The type of the keyspace.") CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.BaseKeyspace, "base-keyspace", "", "The base keyspace for a snapshot keyspace.") CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.SnapshotTimestamp, "snapshot-timestamp", "", "The snapshot time for a snapshot keyspace, as a timestamp in RFC3339 format.") - CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.DurabilityPolicy, "durability-policy", "none", "Type of durability to enforce for this keyspace. Default is none. Possible values include 'semi_sync' and others as dictated by registered plugins.") + CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.DurabilityPolicy, "durability-policy", policy.DurabilityNone, "Type of durability to enforce for this keyspace. Default is none. Possible values include 'semi_sync' and others as dictated by registered plugins.") CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.SidecarDBName, "sidecar-db-name", sidecar.DefaultName, "(Experimental) Name of the Vitess sidecar database that tablets in this keyspace will use for internal metadata.") Root.AddCommand(CreateKeyspace) @@ -425,14 +385,8 @@ func init() { RemoveKeyspaceCell.Flags().BoolVarP(&removeKeyspaceCellOptions.Recursive, "recursive", "r", false, "Also delete all tablets in that cell beloning to the specified keyspace.") Root.AddCommand(RemoveKeyspaceCell) - SetKeyspaceDurabilityPolicy.Flags().StringVar(&setKeyspaceDurabilityPolicyOptions.DurabilityPolicy, "durability-policy", "none", "Type of durability to enforce for this keyspace. Default is none. Other values include 'semi_sync' and others as dictated by registered plugins.") + SetKeyspaceDurabilityPolicy.Flags().StringVar(&setKeyspaceDurabilityPolicyOptions.DurabilityPolicy, "durability-policy", policy.DurabilityNone, "Type of durability to enforce for this keyspace. Default is none. Other values include 'semi_sync' and others as dictated by registered plugins.") Root.AddCommand(SetKeyspaceDurabilityPolicy) - ValidateSchemaKeyspace.Flags().BoolVar(&validateSchemaKeyspaceOptions.IncludeViews, "include-views", false, "Includes views in compared schemas.") - ValidateSchemaKeyspace.Flags().BoolVar(&validateSchemaKeyspaceOptions.IncludeVSchema, "include-vschema", false, "Includes VSchema validation in validation results.") - ValidateSchemaKeyspace.Flags().BoolVar(&validateSchemaKeyspaceOptions.SkipNoPrimary, "skip-no-primary", false, "Skips validation on whether or not a primary exists in shards.") - ValidateSchemaKeyspace.Flags().StringSliceVar(&validateSchemaKeyspaceOptions.ExcludeTables, "exclude-tables", []string{}, "Tables to exclude during schema comparison.") - Root.AddCommand(ValidateSchemaKeyspace) - Root.AddCommand(ValidateVersionKeyspace) } diff --git a/go/cmd/vtctldclient/command/permissions.go b/go/cmd/vtctldclient/command/permissions.go new file mode 100644 index 00000000000..57dc2c5b38e --- /dev/null +++ b/go/cmd/vtctldclient/command/permissions.go @@ -0,0 +1,114 @@ +/* +Copyright 2025 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 command + +import ( + "fmt" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/topo/topoproto" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // GetPermissions makes a GetPermissions gRPC call to a vtctld. + GetPermissions = &cobra.Command{ + Use: "GetPermissions ", + Short: "Displays the permissions for a tablet.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandGetPermissions, + } + // ValidatePermissionsShard makes a ValidatePermissionsKeyspace gRPC call to a + // vtctld with the specified shard to examine in the keyspace. + ValidatePermissionsShard = &cobra.Command{ + Use: "ValidatePermissionsShard ", + Short: "Validates that the permissions on the primary match all of the replicas.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandValidatePermissionsShard, + } + // ValidatePermissionsKeyspace makes a ValidatePermissionsKeyspace gRPC call to a + // vtctld. + ValidatePermissionsKeyspace = &cobra.Command{ + Use: "ValidatePermissionsKeyspace ", + Short: "Validates that the permissions on the primary of the first shard match those of all of the other tablets in the keyspace.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandValidatePermissionsKeyspace, + } +) + +func commandGetPermissions(cmd *cobra.Command, args []string) error { + alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + resp, err := client.GetPermissions(commandCtx, &vtctldatapb.GetPermissionsRequest{ + TabletAlias: alias, + }) + if err != nil { + return err + } + p, err := cli.MarshalJSON(resp.Permissions) + if err != nil { + return err + } + fmt.Printf("%s\n", p) + + return nil +} + +func commandValidatePermissionsKeyspace(cmd *cobra.Command, args []string) error { + keyspace := cmd.Flags().Arg(0) + + cli.FinishedParsing(cmd) + + _, err := client.ValidatePermissionsKeyspace(commandCtx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: keyspace, + }) + + return err +} + +func commandValidatePermissionsShard(cmd *cobra.Command, args []string) error { + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + _, err = client.ValidatePermissionsKeyspace(commandCtx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: keyspace, + Shards: []string{shard}, + }) + + return err +} + +func init() { + Root.AddCommand(GetPermissions) + Root.AddCommand(ValidatePermissionsKeyspace) + Root.AddCommand(ValidatePermissionsShard) +} diff --git a/go/cmd/vtctldclient/command/permissions_test.go b/go/cmd/vtctldclient/command/permissions_test.go new file mode 100644 index 00000000000..a9ddba36f7f --- /dev/null +++ b/go/cmd/vtctldclient/command/permissions_test.go @@ -0,0 +1,608 @@ +/* +Copyright 2025 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 command + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/discovery" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" + "vitess.io/vitess/go/vt/vtenv" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +func TestPermissions(t *testing.T) { + delay := discovery.GetTabletPickerRetryDelay() + defer func() { + discovery.SetTabletPickerRetryDelay(delay) + }() + discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) + + // Initialize our environment. + ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) + defer cancel() + ts := memorytopo.NewServer(ctx, "cell1", "cell2") + defer ts.Close() + vtctld := grpcvtctldserver.NewVtctldServer(vtenv.NewTestEnv(), ts) + + primary := NewFakeTablet(t, ts, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) + replica := NewFakeTablet(t, ts, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + + // Mark the primary for the shard. + _, err := ts.UpdateShardFields(ctx, primary.Tablet.Keyspace, primary.Tablet.Shard, func(si *topo.ShardInfo) error { + si.PrimaryAlias = primary.Tablet.Alias + return nil + }) + require.NoError(t, err) + + // The primary will be asked for permissions. + primary.FakeMysqlDaemon.FetchSuperQueryMap = map[string]*sqltypes.Result{ + "SELECT * FROM mysql.user ORDER BY host, user": { + Fields: []*querypb.Field{ + { + Name: "Host", + Type: sqltypes.Char, + }, + { + Name: "User", + Type: sqltypes.Char, + }, + { + Name: "Password", + Type: sqltypes.Char, + }, + { + Name: "Select_priv", + Type: sqltypes.Char, + }, + { + Name: "Insert_priv", + Type: sqltypes.Char, + }, + { + Name: "Update_priv", + Type: sqltypes.Char, + }, + { + Name: "Delete_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_priv", + Type: sqltypes.Char, + }, + { + Name: "Drop_priv", + Type: sqltypes.Char, + }, + { + Name: "Reload_priv", + Type: sqltypes.Char, + }, + { + Name: "Shutdown_priv", + Type: sqltypes.Char, + }, + { + Name: "Process_priv", + Type: sqltypes.Char, + }, + { + Name: "File_priv", + Type: sqltypes.Char, + }, + { + Name: "Grant_priv", + Type: sqltypes.Char, + }, + { + Name: "References_priv", + Type: sqltypes.Char, + }, + { + Name: "Index_priv", + Type: sqltypes.Char, + }, + { + Name: "Alter_priv", + Type: sqltypes.Char, + }, + { + Name: "Show_db_priv", + Type: sqltypes.Char, + }, + { + Name: "Super_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_tmp_table_priv", + Type: sqltypes.Char, + }, + { + Name: "Lock_tables_priv", + Type: sqltypes.Char, + }, + { + Name: "Execute_priv", + Type: sqltypes.Char, + }, + { + Name: "Repl_slave_priv", + Type: sqltypes.Char, + }, + { + Name: "Repl_client_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_view_priv", + Type: sqltypes.Char, + }, + { + Name: "Show_view_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_routine_priv", + Type: sqltypes.Char, + }, + { + Name: "Alter_routine_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_user_priv", + Type: sqltypes.Char, + }, + { + Name: "Event_priv", + Type: sqltypes.Char, + }, + { + Name: "Trigger_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_tablespace_priv", + Type: sqltypes.Char, + }, + { + Name: "ssl_type", + Type: sqltypes.Char, + }, + { + Name: "ssl_cipher", + Type: 252, + }, + { + Name: "x509_issuer", + Type: 252, + }, + { + Name: "x509_subject", + Type: 252, + }, + { + Name: "max_questions", + Type: 3, + }, + { + Name: "max_updates", + Type: 3, + }, + { + Name: "max_connections", + Type: 3, + }, + { + Name: "max_user_connections", + Type: 3, + }, + { + Name: "plugin", + Type: sqltypes.Char, + }, + { + Name: "authentication_string", + Type: 252, + }, + { + Name: "password_expired", + Type: sqltypes.Char, + }, + { + Name: "is_role", + Type: sqltypes.Char, + }}, + RowsAffected: 0x6, + InsertID: 0x0, + Rows: [][]sqltypes.Value{ + { + sqltypes.NewVarBinary("test_host1"), + sqltypes.NewVarBinary("test_user1"), + sqltypes.NewVarBinary("test_password1"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N")}, + { + sqltypes.NewVarBinary("test_host2"), + sqltypes.NewVarBinary("test_user2"), + sqltypes.NewVarBinary("test_password2"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N")}, + { + sqltypes.NewVarBinary("test_host3"), + sqltypes.NewVarBinary("test_user3"), + sqltypes.NewVarBinary("test_password3"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N")}, + { + sqltypes.NewVarBinary("test_host4"), + sqltypes.NewVarBinary("test_user4"), + sqltypes.NewVarBinary("test_password4"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary("0"), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary(""), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("N"), + }, + }, + }, + "SELECT * FROM mysql.db ORDER BY host, db, user": { + Fields: []*querypb.Field{ + { + Name: "Host", + Type: sqltypes.Char, + }, + { + Name: "Db", + Type: sqltypes.Char, + }, + { + Name: "User", + Type: sqltypes.Char, + }, + { + Name: "Select_priv", + Type: sqltypes.Char, + }, + { + Name: "Insert_priv", + Type: sqltypes.Char, + }, + { + Name: "Update_priv", + Type: sqltypes.Char, + }, + { + Name: "Delete_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_priv", + Type: sqltypes.Char, + }, + { + Name: "Drop_priv", + Type: sqltypes.Char, + }, + { + Name: "Grant_priv", + Type: sqltypes.Char, + }, + { + Name: "References_priv", + Type: sqltypes.Char, + }, + { + Name: "Index_priv", + Type: sqltypes.Char, + }, + { + Name: "Alter_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_tmp_table_priv", + Type: sqltypes.Char, + }, + { + Name: "Lock_tables_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_view_priv", + Type: sqltypes.Char, + }, + { + Name: "Show_view_priv", + Type: sqltypes.Char, + }, + { + Name: "Create_routine_priv", + Type: sqltypes.Char, + }, + { + Name: "Alter_routine_priv", + Type: sqltypes.Char, + }, + { + Name: "Execute_priv", + Type: sqltypes.Char, + }, + { + Name: "Event_priv", + Type: sqltypes.Char, + }, + { + Name: "Trigger_priv", + Type: sqltypes.Char, + }, + }, + RowsAffected: 0, + InsertID: 0, + Rows: [][]sqltypes.Value{ + { + sqltypes.NewVarBinary("test_host"), + sqltypes.NewVarBinary("test_db"), + sqltypes.NewVarBinary("test_user"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("N"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + sqltypes.NewVarBinary("Y"), + }, + }, + }, + } + primary.StartActionLoop(t, ts) + defer primary.StopActionLoop(t) + + // Make a two-level-deep copy, so we can make them diverge later. + user := *primary.FakeMysqlDaemon.FetchSuperQueryMap["SELECT * FROM mysql.user ORDER BY host, user"] + user.Fields = append([]*querypb.Field{}, user.Fields...) + + // The replica will be asked for permissions. + replica.FakeMysqlDaemon.FetchSuperQueryMap = map[string]*sqltypes.Result{ + "SELECT * FROM mysql.user ORDER BY host, user": &user, + "SELECT * FROM mysql.db ORDER BY host, db, user": primary.FakeMysqlDaemon.FetchSuperQueryMap["SELECT * FROM mysql.db ORDER BY host, db, user"], + } + replica.FakeMysqlDaemon.SetReplicationSourceInputs = append(replica.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) + replica.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + // These 3 statements come from tablet startup. + "STOP REPLICA", + "FAKE SET SOURCE", + "START REPLICA", + } + replica.StartActionLoop(t, ts) + defer replica.StopActionLoop(t) + + // Overwrite with the correct value to make sure it passes. + replica.FakeMysqlDaemon.FetchSuperQueryMap["SELECT * FROM mysql.user ORDER BY host, user"].Fields[0] = &querypb.Field{ + Name: "Host", + Type: sqltypes.Char, + } + + _, err = vtctld.GetPermissions(ctx, &vtctldatapb.GetPermissionsRequest{ + TabletAlias: primary.Tablet.Alias, + }) + require.NoError(t, err) + + _, err = vtctld.ValidatePermissionsKeyspace(ctx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: primary.Tablet.Keyspace, + }) + require.NoError(t, err) + _, err = vtctld.ValidatePermissionsKeyspace(ctx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: primary.Tablet.Keyspace, + Shards: []string{primary.Tablet.Shard}, + }) + require.NoError(t, err) + + // Modify one field, which should result in a validation failure/error. + replica.FakeMysqlDaemon.FetchSuperQueryMap["SELECT * FROM mysql.user ORDER BY host, user"].Fields[0] = &querypb.Field{ + Name: "Wrong", + Type: sqltypes.Char, + } + _, err = vtctld.ValidatePermissionsKeyspace(ctx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: primary.Tablet.Keyspace, + }) + require.ErrorContains(t, err, "has an extra user") + _, err = vtctld.ValidatePermissionsKeyspace(ctx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: primary.Tablet.Keyspace, + Shards: []string{primary.Tablet.Shard}, + }) + require.ErrorContains(t, err, "has an extra user") +} diff --git a/go/cmd/vtctldclient/command/root.go b/go/cmd/vtctldclient/command/root.go index 3ebe019f94d..2a65a59f606 100644 --- a/go/cmd/vtctldclient/command/root.go +++ b/go/cmd/vtctldclient/command/root.go @@ -37,7 +37,6 @@ import ( "vitess.io/vitess/go/vt/vtctl/localvtctldclient" "vitess.io/vitess/go/vt/vtctl/vtctldclient" "vitess.io/vitess/go/vt/vtenv" - "vitess.io/vitess/go/vt/vttablet/tmclient" // These imports ensure init()s within them get called and they register their commands/subcommands. "vitess.io/vitess/go/cmd/vtctldclient/cli" @@ -97,8 +96,8 @@ var ( // Root is the main entrypoint to the vtctldclient CLI. Root = &cobra.Command{ Use: "vtctldclient", - Short: "Executes a cluster management command on the remote vtctld server.", - Long: fmt.Sprintf(`Executes a cluster management command on the remote vtctld server. + Short: "Executes a cluster management command on the remote vtctld server or alternatively as a standalone binary using --server=internal.", + Long: fmt.Sprintf(`Executes a cluster management command on the remote vtctld server or alternatively as a standalone binary using --server=internal. If there are no running vtctld servers -- for example when bootstrapping a new Vitess cluster -- you can specify a --server value of '%s'. When doing so, you would use the --topo* flags so that the client can @@ -204,14 +203,6 @@ func getClientForCommand(cmd *cobra.Command) (vtctldclient.VtctldClient, error) } onTerm = append(onTerm, ts.Close) - // Use internal vtctld server implementation. - // Register a nil grpc handler -- we will not use tmclient at all but - // a factory still needs to be registered. - once.Do(func() { - tmclient.RegisterTabletManagerClientFactory("grpc", func() tmclient.TabletManagerClient { - return nil - }) - }) vtctld := grpcvtctldserver.NewVtctldServer(env, ts) localvtctldclient.SetServer(vtctld) VtctldClientProtocol = "local" diff --git a/go/cmd/vtctldclient/command/root_test.go b/go/cmd/vtctldclient/command/root_test.go index 86333ec0e69..0f0cdca8dcd 100644 --- a/go/cmd/vtctldclient/command/root_test.go +++ b/go/cmd/vtctldclient/command/root_test.go @@ -67,15 +67,15 @@ func TestRootWithInternalVtctld(t *testing.T) { cell := "zone1" ts, factory := memorytopo.NewServerAndFactory(ctx, cell) topo.RegisterFactory("test", factory) + origProtocol := command.VtctldClientProtocol command.VtctldClientProtocol = "local" baseArgs := []string{"vtctldclient", "--server", "internal", "--topo-implementation", "test"} args := append([]string{}, os.Args...) - protocol := command.VtctldClientProtocol t.Cleanup(func() { ts.Close() os.Args = append([]string{}, args...) - command.VtctldClientProtocol = protocol + command.VtctldClientProtocol = origProtocol }) testCases := []struct { diff --git a/go/cmd/vtctldclient/command/schema.go b/go/cmd/vtctldclient/command/schema.go index db34bd2588f..21a995f30a1 100644 --- a/go/cmd/vtctldclient/command/schema.go +++ b/go/cmd/vtctldclient/command/schema.go @@ -32,8 +32,9 @@ import ( "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" - "vitess.io/vitess/go/vt/proto/vtrpc" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) var ( @@ -58,6 +59,13 @@ For --sql, semi-colons and repeated values may be mixed, for example: Args: cobra.ExactArgs(1), RunE: commandApplySchema, } + CopySchemaShard = &cobra.Command{ + Use: "CopySchemaShard [--tables=,,...] [--exclude-tables=,,...] [--include-views] [--skip-verify] [--wait-replicas-timeout=10s] { || } ", + Short: "Copies the schema from a source shard's primary (or a specific tablet) to a destination shard. The schema is applied directly on the primary of the destination shard, and it is propagated to the replicas through binlogs.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(2), + RunE: commandCopySchemaShard, + } // GetSchema makes a GetSchema gRPC call to a vtctld. GetSchema = &cobra.Command{ Use: "GetSchema [--tables TABLES ...] [--exclude-tables EXCLUDE_TABLES ...] [{--table-names-only | --table-sizes-only}] [--include-views] alias", @@ -90,6 +98,25 @@ For --sql, semi-colons and repeated values may be mixed, for example: Args: cobra.ExactArgs(1), RunE: commandReloadSchemaShard, } + // ValidateSchemaKeyspace makes a ValidateSchemaKeyspace gRPC call to a vtctld. + ValidateSchemaKeyspace = &cobra.Command{ + Use: "ValidateSchemaKeyspace [--exclude-tables=] [--include-views] [--skip-no-primary] [--include-vschema] ", + Short: "Validates that the schema on the primary tablet for the first shard matches the schema on all other tablets in the keyspace.", + DisableFlagsInUseLine: true, + Aliases: []string{"validateschemakeyspace"}, + Args: cobra.ExactArgs(1), + RunE: commandValidateSchemaKeyspace, + } + // ValidateSchemaShard makes a ValidateSchemaKeyspace gRPC call to a vtctld with + // the specified shard to examine in the keyspace. + ValidateSchemaShard = &cobra.Command{ + Use: "ValidateSchemaShard [--exclude-tables=] [--include-views] [--skip-no-primary] [--include-vschema] ", + Short: "Validates that the schema on the primary tablet for the specified shard matches the schema on all other tablets in that shard.", + DisableFlagsInUseLine: true, + Aliases: []string{"validateschemashard"}, + Args: cobra.ExactArgs(1), + RunE: commandValidateSchemaShard, + } ) var applySchemaOptions = struct { @@ -129,9 +156,9 @@ func commandApplySchema(cmd *cobra.Command, args []string) error { cli.FinishedParsing(cmd) - var cid *vtrpc.CallerID + var cid *vtrpcpb.CallerID if applySchemaOptions.CallerID != "" { - cid = &vtrpc.CallerID{Principal: applySchemaOptions.CallerID} + cid = &vtrpcpb.CallerID{Principal: applySchemaOptions.CallerID} } ks := cmd.Flags().Arg(0) @@ -154,6 +181,61 @@ func commandApplySchema(cmd *cobra.Command, args []string) error { return nil } +var copySchemaShardOptions = struct { + tables []string + excludeTables []string + includeViews bool + skipVerify bool + waitReplicasTimeout time.Duration +}{} + +func commandCopySchemaShard(cmd *cobra.Command, args []string) error { + destKeyspace, destShard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(1)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + var sourceTabletAlias *topodatapb.TabletAlias + sourceKeyspace, sourceShard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err == nil { + res, err := client.GetTablets(commandCtx, &vtctldatapb.GetTabletsRequest{ + Keyspace: sourceKeyspace, + Shard: sourceShard, + TabletType: topodatapb.TabletType_PRIMARY, + }) + if err != nil { + return err + } + tablets := res.GetTablets() + if len(tablets) == 0 { + return fmt.Errorf("no primary tablet found in source shard %s/%s", sourceKeyspace, sourceShard) + } + sourceTabletAlias = tablets[0].Alias + } else { + sourceTabletAlias, err = topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) + if err != nil { + return err + } + } + + req := &vtctldatapb.CopySchemaShardRequest{ + SourceTabletAlias: sourceTabletAlias, + Tables: copySchemaShardOptions.tables, + ExcludeTables: copySchemaShardOptions.excludeTables, + IncludeViews: copySchemaShardOptions.includeViews, + SkipVerify: copySchemaShardOptions.skipVerify, + WaitReplicasTimeout: protoutil.DurationToProto(copySchemaShardOptions.waitReplicasTimeout), + DestinationKeyspace: destKeyspace, + DestinationShard: destShard, + } + + _, err = client.CopySchemaShard(commandCtx, req) + + return err +} + var getSchemaOptions = struct { Tables []string ExcludeTables []string @@ -284,6 +366,69 @@ func commandReloadSchemaShard(cmd *cobra.Command, args []string) error { return err } +var validateSchemaKeyspaceOptions = struct { + ExcludeTables []string + IncludeViews bool + SkipNoPrimary bool + IncludeVSchema bool + Shard string +}{} + +func commandValidateSchemaKeyspace(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + + keyspace := cmd.Flags().Arg(0) + resp, err := client.ValidateSchemaKeyspace(commandCtx, &vtctldatapb.ValidateSchemaKeyspaceRequest{ + Keyspace: keyspace, + ExcludeTables: validateSchemaKeyspaceOptions.ExcludeTables, + IncludeVschema: validateSchemaKeyspaceOptions.IncludeVSchema, + SkipNoPrimary: validateSchemaKeyspaceOptions.SkipNoPrimary, + IncludeViews: validateSchemaKeyspaceOptions.IncludeViews, + }) + + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.ResultsByShard) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + return nil +} + +func commandValidateSchemaShard(cmd *cobra.Command, args []string) error { + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + resp, err := client.ValidateSchemaKeyspace(commandCtx, &vtctldatapb.ValidateSchemaKeyspaceRequest{ + Keyspace: keyspace, + Shards: []string{shard}, + ExcludeTables: validateSchemaKeyspaceOptions.ExcludeTables, + IncludeVschema: validateSchemaKeyspaceOptions.IncludeVSchema, + SkipNoPrimary: validateSchemaKeyspaceOptions.SkipNoPrimary, + IncludeViews: validateSchemaKeyspaceOptions.IncludeViews, + }) + + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.Results) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + return nil +} + func init() { ApplySchema.Flags().StringVar(&applySchemaOptions.DDLStrategy, "ddl-strategy", string(schema.DDLStrategyDirect), "Online DDL strategy, compatible with @@ddl_strategy session variable (examples: 'gh-ost', 'pt-osc', 'gh-ost --max-load=Threads_running=100'.") ApplySchema.Flags().StringSliceVar(&applySchemaOptions.UUIDList, "uuid", nil, "Optional, comma-delimited, repeatable, explicit UUIDs for migration. If given, must match number of DDL changes.") @@ -293,16 +438,21 @@ func init() { ApplySchema.Flags().StringArrayVar(&applySchemaOptions.SQL, "sql", nil, "Semicolon-delimited, repeatable SQL commands to apply. Exactly one of --sql|--sql-file is required.") ApplySchema.Flags().StringVar(&applySchemaOptions.SQLFile, "sql-file", "", "Path to a file containing semicolon-delimited SQL commands to apply. Exactly one of --sql|--sql-file is required.") ApplySchema.Flags().Int64Var(&applySchemaOptions.BatchSize, "batch-size", 0, "How many queries to batch together. Only applicable when all queries are CREATE TABLE|VIEW") - Root.AddCommand(ApplySchema) + CopySchemaShard.Flags().StringSliceVar(©SchemaShardOptions.tables, "tables", nil, "Specifies a comma-separated list of tables to copy. Each is either an exact match, or a regular expression of the form /regexp/") + CopySchemaShard.Flags().StringSliceVar(©SchemaShardOptions.excludeTables, "exclude-tables", nil, "Specifies a comma-separated list of tables to exclude. Each is either an exact match, or a regular expression of the form /regexp/") + CopySchemaShard.Flags().BoolVar(©SchemaShardOptions.includeViews, "include-views", true, "Includes views in the output") + CopySchemaShard.Flags().BoolVar(©SchemaShardOptions.skipVerify, "skip-verify", false, "Skip verification of source and target schema after copy") + CopySchemaShard.Flags().DurationVar(©SchemaShardOptions.waitReplicasTimeout, "wait-replicas-timeout", grpcvtctldserver.DefaultWaitReplicasTimeout, "The amount of time to wait for replicas to receive the schema change via replication.") + Root.AddCommand(CopySchemaShard) + GetSchema.Flags().StringSliceVar(&getSchemaOptions.Tables, "tables", nil, "List of tables to display the schema for. Each is either an exact match, or a regular expression of the form `/regexp/`.") GetSchema.Flags().StringSliceVar(&getSchemaOptions.ExcludeTables, "exclude-tables", nil, "List of tables to exclude from the result. Each is either an exact match, or a regular expression of the form `/regexp/`.") GetSchema.Flags().BoolVar(&getSchemaOptions.IncludeViews, "include-views", false, "Includes views in the output in addition to base tables.") GetSchema.Flags().BoolVarP(&getSchemaOptions.TableNamesOnly, "table-names-only", "n", false, "Display only table names in the result.") GetSchema.Flags().BoolVarP(&getSchemaOptions.TableSizesOnly, "table-sizes-only", "s", false, "Display only size information for matching tables. Ignored if --table-names-only is set.") GetSchema.Flags().BoolVarP(&getSchemaOptions.TableSchemaOnly, "table-schema-only", "", false, "Skip introspecting columns and fields metadata.") - Root.AddCommand(GetSchema) Root.AddCommand(ReloadSchema) @@ -314,4 +464,16 @@ func init() { ReloadSchemaShard.Flags().Int32Var(&reloadSchemaShardOptions.Concurrency, "concurrency", 10, "Number of tablets to reload in parallel. Set to zero for unbounded concurrency.") ReloadSchemaShard.Flags().BoolVar(&reloadSchemaShardOptions.IncludePrimary, "include-primary", false, "Also reload the primary tablet.") Root.AddCommand(ReloadSchemaShard) + + ValidateSchemaKeyspace.Flags().BoolVar(&validateSchemaKeyspaceOptions.IncludeViews, "include-views", false, "Includes views in compared schemas.") + ValidateSchemaKeyspace.Flags().BoolVar(&validateSchemaKeyspaceOptions.IncludeVSchema, "include-vschema", false, "Includes VSchema validation in validation results.") + ValidateSchemaKeyspace.Flags().BoolVar(&validateSchemaKeyspaceOptions.SkipNoPrimary, "skip-no-primary", false, "Skips validation on whether or not a primary exists in shards.") + ValidateSchemaKeyspace.Flags().StringSliceVar(&validateSchemaKeyspaceOptions.ExcludeTables, "exclude-tables", []string{}, "Tables to exclude during schema comparison.") + Root.AddCommand(ValidateSchemaKeyspace) + + ValidateSchemaShard.Flags().BoolVar(&validateSchemaKeyspaceOptions.IncludeViews, "include-views", false, "Includes views in compared schemas.") + ValidateSchemaShard.Flags().BoolVar(&validateSchemaKeyspaceOptions.IncludeVSchema, "include-vschema", false, "Includes VSchema validation in validation results.") + ValidateSchemaShard.Flags().BoolVar(&validateSchemaKeyspaceOptions.SkipNoPrimary, "skip-no-primary", false, "Skips validation on whether or not a primary exists in shards.") + ValidateSchemaShard.Flags().StringSliceVar(&validateSchemaKeyspaceOptions.ExcludeTables, "exclude-tables", []string{}, "Tables to exclude during schema comparison.") + Root.AddCommand(ValidateSchemaShard) } diff --git a/go/cmd/vtctldclient/command/tablets.go b/go/cmd/vtctldclient/command/tablets.go index bb468fbd7ff..3ee7de1e867 100644 --- a/go/cmd/vtctldclient/command/tablets.go +++ b/go/cmd/vtctldclient/command/tablets.go @@ -92,14 +92,6 @@ Note: hook names may not contain slash (/) characters. Args: cobra.ExactArgs(1), RunE: commandGetFullStatus, } - // GetPermissions makes a GetPermissions gRPC call to a vtctld. - GetPermissions = &cobra.Command{ - Use: "GetPermissions ", - Short: "Displays the permissions for a tablet.", - DisableFlagsInUseLine: true, - Args: cobra.ExactArgs(1), - RunE: commandGetPermissions, - } // GetTablet makes a GetTablet gRPC call to a vtctld. GetTablet = &cobra.Command{ Use: "GetTablet ", @@ -380,29 +372,6 @@ func commandGetFullStatus(cmd *cobra.Command, args []string) error { return nil } -func commandGetPermissions(cmd *cobra.Command, args []string) error { - alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) - if err != nil { - return err - } - - cli.FinishedParsing(cmd) - - resp, err := client.GetPermissions(commandCtx, &vtctldatapb.GetPermissionsRequest{ - TabletAlias: alias, - }) - if err != nil { - return err - } - p, err := cli.MarshalJSON(resp.Permissions) - if err != nil { - return err - } - fmt.Printf("%s\n", p) - - return nil -} - func commandGetTablet(cmd *cobra.Command, args []string) error { aliasStr := cmd.Flags().Arg(0) alias, err := topoproto.ParseTabletAlias(aliasStr) @@ -685,7 +654,6 @@ func init() { Root.AddCommand(ExecuteHook) Root.AddCommand(GetFullStatus) - Root.AddCommand(GetPermissions) Root.AddCommand(GetTablet) GetTablets.Flags().StringSliceVarP(&getTabletsOptions.TabletAliasStrings, "tablet-alias", "t", nil, "List of tablet aliases to filter by.") diff --git a/go/cmd/vtctldclient/command/topology.go b/go/cmd/vtctldclient/command/topology.go index 6aa6949341c..a03ce403eb8 100644 --- a/go/cmd/vtctldclient/command/topology.go +++ b/go/cmd/vtctldclient/command/topology.go @@ -18,10 +18,13 @@ package command import ( "fmt" + "os" + "strings" "github.com/spf13/cobra" "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/topo" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -36,12 +39,30 @@ var ( RunE: commandGetTopologyPath, } + // WriteTopologyPath writes the contents of a local file to a path + // in the topology server. + WriteTopologyPath = &cobra.Command{ + Use: "WriteTopologyPath --server=local ", + Short: "Copies a local file to the topology server at the given path.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(2), + PreRunE: func(cmd *cobra.Command, args []string) error { + if VtctldClientProtocol != "local" { + return fmt.Errorf("The WriteTopologyPath command can only be used with --server=%s", useInternalVtctld) + } + return nil + }, + RunE: commandWriteTopologyPath, + } +) + +var getTopologyPathOptions = struct { // The version of the key/path to get. If not specified, the latest/current // version is returned. - version int64 = 0 + version int64 // If true, only the data is output and it is in JSON format rather than prototext. - dataAsJSON bool = false -) + dataAsJSON bool +}{} func commandGetTopologyPath(cmd *cobra.Command, args []string) error { path := cmd.Flags().Arg(0) @@ -50,14 +71,14 @@ func commandGetTopologyPath(cmd *cobra.Command, args []string) error { resp, err := client.GetTopologyPath(commandCtx, &vtctldatapb.GetTopologyPathRequest{ Path: path, - Version: version, - AsJson: dataAsJSON, + Version: getTopologyPathOptions.version, + AsJson: getTopologyPathOptions.dataAsJSON, }) if err != nil { return err } - if dataAsJSON { + if getTopologyPathOptions.dataAsJSON { if resp.GetCell() == nil || resp.GetCell().GetData() == "" { return fmt.Errorf("no data found for path %s", path) } @@ -75,8 +96,41 @@ func commandGetTopologyPath(cmd *cobra.Command, args []string) error { return nil } +var writeTopologyPathOptions = struct { + // The cell to use for the copy. Defaults to the global cell. + cell string +}{} + +func commandWriteTopologyPath(cmd *cobra.Command, args []string) error { + file := cmd.Flags().Arg(0) + path := cmd.Flags().Arg(1) + ts, err := topo.OpenServer(topoOptions.implementation, strings.Join(topoOptions.globalServerAddresses, ","), topoOptions.globalRoot) + if err != nil { + return fmt.Errorf("failed to connect to the topology server: %v", err) + } + cli.FinishedParsing(cmd) + + conn, err := ts.ConnForCell(cmd.Context(), writeTopologyPathOptions.cell) + if err != nil { + return fmt.Errorf("failed to connect to the topology server: %v", err) + } + data, err := os.ReadFile(file) + if err != nil { + return fmt.Errorf("failed to read file %s: %v", file, err) + } + _, err = conn.Update(cmd.Context(), path, data, nil) + if err != nil { + return fmt.Errorf("failed to write to topology server path %s: %v", path, err) + } + + return nil +} + func init() { - GetTopologyPath.Flags().Int64Var(&version, "version", version, "The version of the path's key to get. If not specified, the latest version is returned.") - GetTopologyPath.Flags().BoolVar(&dataAsJSON, "data-as-json", dataAsJSON, "If true, only the data is output and it is in JSON format rather than prototext.") + GetTopologyPath.Flags().Int64Var(&getTopologyPathOptions.version, "version", getTopologyPathOptions.version, "The version of the path's key to get. If not specified, the latest version is returned.") + GetTopologyPath.Flags().BoolVar(&getTopologyPathOptions.dataAsJSON, "data-as-json", getTopologyPathOptions.dataAsJSON, "If true, only the data is output and it is in JSON format rather than prototext.") Root.AddCommand(GetTopologyPath) + + WriteTopologyPath.Flags().StringVar(&writeTopologyPathOptions.cell, "cell", topo.GlobalCell, "Topology server cell to copy the file to.") + Root.AddCommand(WriteTopologyPath) } diff --git a/go/cmd/vtctldclient/command/vreplication/lookupvindex/lookupvindex.go b/go/cmd/vtctldclient/command/vreplication/lookupvindex/lookupvindex.go index 9650a52e8a5..82b13cf70b3 100644 --- a/go/cmd/vtctldclient/command/vreplication/lookupvindex/lookupvindex.go +++ b/go/cmd/vtctldclient/command/vreplication/lookupvindex/lookupvindex.go @@ -72,6 +72,15 @@ var ( externalizeOptions = struct { Keyspace string + Delete bool + }{} + + internalizeOptions = struct { + Keyspace string + }{} + + completeOptions = struct { + Keyspace string }{} parseAndValidateCreate = func(cmd *cobra.Command, args []string) error { @@ -142,6 +151,18 @@ var ( RunE: commandCancel, } + // complete makes a LookupVindexComplete call to a vtctld. + complete = &cobra.Command{ + Use: "complete", + Short: "Complete the LookupVindex workflow. The Vindex must have been previously externalized. If you want to delete the workflow without externalizing the Vindex then use the cancel command instead.", + Example: `vtctldclient --server localhost:15999 LookupVindex --name corder_lookup_vdx --table-keyspace customer complete`, + SilenceUsage: true, + DisableFlagsInUseLine: true, + Aliases: []string{"Complete"}, + Args: cobra.NoArgs, + RunE: commandComplete, + } + // create makes a LookupVindexCreate call to a vtctld. create = &cobra.Command{ Use: "create", @@ -158,7 +179,7 @@ var ( // externalize makes a LookupVindexExternalize call to a vtctld. externalize = &cobra.Command{ Use: "externalize", - Short: "Externalize the Lookup Vindex. If the Vindex has an owner the VReplication workflow will also be deleted.", + Short: "Externalize the Lookup Vindex. If the Vindex has an owner the VReplication workflow will also be stopped/deleted.", Example: `vtctldclient --server localhost:15999 LookupVindex --name corder_lookup_vdx --table-keyspace customer externalize`, SilenceUsage: true, DisableFlagsInUseLine: true, @@ -167,6 +188,18 @@ var ( RunE: commandExternalize, } + // internalize makes a LookupVindexInternalize call to a vtctld. + internalize = &cobra.Command{ + Use: "internalize", + Short: "Internalize the Vindex again to continue the backfill, making it unusable for queries again.", + Example: `vtctldclient --server localhost:15999 LookupVindex --name corder_lookup_vdx --table-keyspace customer internalize`, + SilenceUsage: true, + DisableFlagsInUseLine: true, + Aliases: []string{"Internalize"}, + Args: cobra.NoArgs, + RunE: commandInternalize, + } + // show makes a GetWorkflows call to a vtctld. show = &cobra.Command{ Use: "show", @@ -199,6 +232,30 @@ func commandCancel(cmd *cobra.Command, args []string) error { return nil } +func commandComplete(cmd *cobra.Command, args []string) error { + if completeOptions.Keyspace == "" { + completeOptions.Keyspace = baseOptions.TableKeyspace + } + cli.FinishedParsing(cmd) + + _, err := common.GetClient().LookupVindexComplete(common.GetCommandCtx(), &vtctldatapb.LookupVindexCompleteRequest{ + Keyspace: completeOptions.Keyspace, + // The name of the workflow and lookup vindex. + Name: baseOptions.Name, + // Where the lookup table and VReplication workflow were created. + TableKeyspace: baseOptions.TableKeyspace, + }) + + if err != nil { + return err + } + + output := fmt.Sprintf("LookupVindex %s has been completed and the VReplication workflow has been deleted.", baseOptions.Name) + fmt.Println(output) + + return nil +} + func commandCreate(cmd *cobra.Command, args []string) error { tsp := common.GetTabletSelectionPreference(cmd) cli.FinishedParsing(cmd) @@ -236,6 +293,8 @@ func commandExternalize(cmd *cobra.Command, args []string) error { Name: baseOptions.Name, // Where the lookup table and VReplication workflow were created. TableKeyspace: baseOptions.TableKeyspace, + // Delete the workflow after externalizing, instead of stopping. + DeleteWorkflow: externalizeOptions.Delete, }) if err != nil { @@ -243,14 +302,40 @@ func commandExternalize(cmd *cobra.Command, args []string) error { } output := fmt.Sprintf("LookupVindex %s has been externalized", baseOptions.Name) - if resp.WorkflowDeleted { - output = output + fmt.Sprintf(" and the %s VReplication workflow has been deleted", baseOptions.Name) + if resp.WorkflowStopped { + output = output + " and the VReplication workflow has been stopped." + } else if resp.WorkflowDeleted { + output = output + " and the VReplication workflow has been deleted." } fmt.Println(output) return nil } +func commandInternalize(cmd *cobra.Command, args []string) error { + if internalizeOptions.Keyspace == "" { + internalizeOptions.Keyspace = baseOptions.TableKeyspace + } + cli.FinishedParsing(cmd) + + _, err := common.GetClient().LookupVindexInternalize(common.GetCommandCtx(), &vtctldatapb.LookupVindexInternalizeRequest{ + Keyspace: internalizeOptions.Keyspace, + // The name of the workflow and lookup vindex. + Name: baseOptions.Name, + // Where the lookup table and VReplication workflow were created. + TableKeyspace: baseOptions.TableKeyspace, + }) + + if err != nil { + return err + } + + output := fmt.Sprintf("LookupVindex %s has been internalized and the VReplication workflow has been started.", baseOptions.Name) + fmt.Println(output) + + return nil +} + func commandShow(cmd *cobra.Command, args []string) error { cli.FinishedParsing(cmd) @@ -304,12 +389,19 @@ func registerCommands(root *cobra.Command) { // for the VReplication workflow used. base.AddCommand(show) - // This will also delete the VReplication workflow if the + // This will also stop the VReplication workflow if the // vindex has an owner as the lookup vindex will then be // managed by VTGate. externalize.Flags().StringVar(&externalizeOptions.Keyspace, "keyspace", "", "The keyspace containing the Lookup Vindex. If no value is specified then the table-keyspace will be used.") + externalize.Flags().BoolVar(&externalizeOptions.Delete, "delete", false, "Delete the VReplication workflow after externalizing the Vindex, instead of stopping (default false).") base.AddCommand(externalize) + internalize.Flags().StringVar(&internalizeOptions.Keyspace, "keyspace", "", "The keyspace containing the Lookup Vindex. If no value is specified then the table-keyspace will be used.") + base.AddCommand(internalize) + + complete.Flags().StringVar(&completeOptions.Keyspace, "keyspace", "", "The keyspace containing the Lookup Vindex. If no value is specified then the table-keyspace will be used.") + base.AddCommand(complete) + // The cancel command deletes the VReplication workflow used // to backfill the lookup vindex. It ends up making a // WorkflowDelete VtctldServer call. diff --git a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go index 54b2eec0840..a5d07f0502a 100644 --- a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go +++ b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go @@ -17,13 +17,11 @@ limitations under the License. package vdiff import ( - "encoding/json" "fmt" "html/template" "io" "math" "reflect" - "sort" "strings" "time" @@ -438,7 +436,7 @@ State: {{.State}} RowsCompared: {{.RowsCompared}} HasMismatch: {{.HasMismatch}} StartedAt: {{.StartedAt}} -{{if (eq .State "started")}}Progress: {{printf "%.2f" .Progress.Percentage}}%%{{if .Progress.ETA}}, ETA: {{.Progress.ETA}}{{end}}{{end}} +{{if (eq .State "started")}}Progress: {{printf "%.2f" .Progress.Percentage}}%{{if .Progress.ETA}}, ETA: {{.Progress.ETA}}{{end}}{{end}} {{if .CompletedAt}}CompletedAt: {{.CompletedAt}}{{end}} {{range $table := .TableSummaryMap}} Table {{$table.TableName}}: @@ -579,7 +577,7 @@ func buildRecentListings(resp *vtctldatapb.VDiffShowResponse) ([]*listing, error func displayShowSingleSummary(out io.Writer, format, keyspace, workflowName, uuid string, resp *vtctldatapb.VDiffShowResponse, verbose bool) (vdiff.VDiffState, error) { state := vdiff.UnknownState var output string - summary, err := buildSingleSummary(keyspace, workflowName, uuid, resp, verbose) + summary, err := workflow.BuildSummary(keyspace, workflowName, uuid, resp, verbose) if err != nil { return state, err } @@ -616,225 +614,6 @@ func displayShowSingleSummary(out io.Writer, format, keyspace, workflowName, uui return state, nil } -func buildSingleSummary(keyspace, workflow, uuid string, resp *vtctldatapb.VDiffShowResponse, verbose bool) (*summary, error) { - summary := &summary{ - Workflow: workflow, - Keyspace: keyspace, - UUID: uuid, - State: vdiff.UnknownState, - RowsCompared: 0, - StartedAt: "", - CompletedAt: "", - HasMismatch: false, - Shards: "", - Reports: make(map[string]map[string]vdiff.DiffReport), - Errors: make(map[string]string), - Progress: nil, - } - - var tableSummaryMap map[string]tableSummary - var reports map[string]map[string]vdiff.DiffReport - // Keep a tally of the states across all tables in all shards. - tableStateCounts := map[vdiff.VDiffState]int{ - vdiff.UnknownState: 0, - vdiff.PendingState: 0, - vdiff.StartedState: 0, - vdiff.StoppedState: 0, - vdiff.ErrorState: 0, - vdiff.CompletedState: 0, - } - // Keep a tally of the summary states across all shards. - shardStateCounts := map[vdiff.VDiffState]int{ - vdiff.UnknownState: 0, - vdiff.PendingState: 0, - vdiff.StartedState: 0, - vdiff.StoppedState: 0, - vdiff.ErrorState: 0, - vdiff.CompletedState: 0, - } - // Keep a tally of the approximate total rows to process as we'll use this for our progress - // report. - totalRowsToCompare := int64(0) - var shards []string - for shard, resp := range resp.TabletResponses { - first := true - if resp != nil && resp.Output != nil { - shards = append(shards, shard) - qr := sqltypes.Proto3ToResult(resp.Output) - if tableSummaryMap == nil { - tableSummaryMap = make(map[string]tableSummary, 0) - reports = make(map[string]map[string]vdiff.DiffReport, 0) - } - for _, row := range qr.Named().Rows { - // Update the global VDiff summary based on the per shard level summary. - // Since these values will be the same for all subsequent rows we only use - // the first row. - if first { - first = false - // Our timestamps are strings in `2022-06-26 20:43:25` format so we sort - // them lexicographically. - // We should use the earliest started_at across all shards. - if sa := row.AsString("started_at", ""); summary.StartedAt == "" || sa < summary.StartedAt { - summary.StartedAt = sa - } - // And we should use the latest completed_at across all shards. - if ca := row.AsString("completed_at", ""); summary.CompletedAt == "" || ca > summary.CompletedAt { - summary.CompletedAt = ca - } - // If we had an error on the shard, then let's add that to the summary. - if le := row.AsString("last_error", ""); le != "" { - summary.Errors[shard] = le - } - // Keep track of how many shards are marked as a specific state. We check - // this combined with the shard.table states to determine the VDiff summary - // state. - shardStateCounts[vdiff.VDiffState(strings.ToLower(row.AsString("vdiff_state", "")))]++ - } - - // Global VDiff summary updates that take into account the per table details - // per shard. - { - summary.RowsCompared += row.AsInt64("rows_compared", 0) - totalRowsToCompare += row.AsInt64("table_rows", 0) - - // If we had a mismatch on any table on any shard then the global VDiff - // summary does too. - if mm, _ := row.ToBool("has_mismatch"); mm { - summary.HasMismatch = true - } - } - - // Table summary information that must be accounted for across all shards. - { - table := row.AsString("table_name", "") - if table == "" { // This occurs when the table diff has not started on 1 or more shards - continue - } - // Create the global VDiff table summary object if it doesn't exist. - if _, ok := tableSummaryMap[table]; !ok { - tableSummaryMap[table] = tableSummary{ - TableName: table, - State: vdiff.UnknownState, - } - - } - ts := tableSummaryMap[table] - // This is the shard level VDiff table state. - sts := vdiff.VDiffState(strings.ToLower(row.AsString("table_state", ""))) - tableStateCounts[sts]++ - - // The error state must be sticky, and we should not override any other - // known state with completed. - switch sts { - case vdiff.CompletedState: - if ts.State == vdiff.UnknownState { - ts.State = sts - } - case vdiff.ErrorState: - ts.State = sts - default: - if ts.State != vdiff.ErrorState { - ts.State = sts - } - } - - diffReport := row.AsString("report", "") - dr := vdiff.DiffReport{} - if diffReport != "" { - err := json.Unmarshal([]byte(diffReport), &dr) - if err != nil { - return nil, err - } - ts.RowsCompared += dr.ProcessedRows - ts.MismatchedRows += dr.MismatchedRows - ts.MatchingRows += dr.MatchingRows - ts.ExtraRowsTarget += dr.ExtraRowsTarget - ts.ExtraRowsSource += dr.ExtraRowsSource - } - if _, ok := reports[table]; !ok { - reports[table] = make(map[string]vdiff.DiffReport) - } - - reports[table][shard] = dr - tableSummaryMap[table] = ts - } - } - } - } - - // The global VDiff summary should progress from pending->started->completed with - // stopped for any shard and error for any table being sticky for the global summary. - // We should only consider the VDiff to be complete if it's completed for every table - // on every shard. - if shardStateCounts[vdiff.StoppedState] > 0 { - summary.State = vdiff.StoppedState - } else if shardStateCounts[vdiff.ErrorState] > 0 || tableStateCounts[vdiff.ErrorState] > 0 { - summary.State = vdiff.ErrorState - } else if tableStateCounts[vdiff.StartedState] > 0 { - summary.State = vdiff.StartedState - } else if tableStateCounts[vdiff.PendingState] > 0 { - summary.State = vdiff.PendingState - } else if tableStateCounts[vdiff.CompletedState] == (len(tableSummaryMap) * len(shards)) { - // When doing shard consolidations/merges, we cannot rely solely on the - // vdiff_table state as there are N sources that we process rows from sequentially - // with each one writing to the shared _vt.vdiff_table record for the target shard. - // So we only mark the vdiff for the shard as completed when we've finished - // processing rows from all of the sources -- which is recorded by marking the - // vdiff done for the shard by setting _vt.vdiff.state = completed. - if shardStateCounts[vdiff.CompletedState] == len(shards) { - summary.State = vdiff.CompletedState - } else { - summary.State = vdiff.StartedState - } - } else { - summary.State = vdiff.UnknownState - } - - // If the vdiff has been started then we can calculate the progress. - if summary.State == vdiff.StartedState { - summary.Progress = BuildProgressReport(summary.RowsCompared, totalRowsToCompare, summary.StartedAt) - } - - sort.Strings(shards) // Sort for predictable output - summary.Shards = strings.Join(shards, ",") - summary.TableSummaryMap = tableSummaryMap - summary.Reports = reports - if !summary.HasMismatch && !verbose { - summary.Reports = nil - summary.TableSummaryMap = nil - } - // If we haven't completed the global VDiff then be sure to reflect that with no - // CompletedAt value. - if summary.State != vdiff.CompletedState { - summary.CompletedAt = "" - } - return summary, nil -} - -func BuildProgressReport(rowsCompared int64, rowsToCompare int64, startedAt string) *vdiff.ProgressReport { - report := &vdiff.ProgressReport{} - if rowsCompared >= 1 { - // Round to 2 decimal points. - report.Percentage = math.Round(math.Min((float64(rowsCompared)/float64(rowsToCompare))*100, 100.00)*100) / 100 - } - if math.IsNaN(report.Percentage) { - report.Percentage = 0 - } - pctToGo := math.Abs(report.Percentage - 100.00) - startTime, _ := time.Parse(vdiff.TimestampFormat, startedAt) - curTime := time.Now().UTC() - runTime := curTime.Unix() - startTime.Unix() - if report.Percentage >= 1 { - // Calculate how long 1% took, on avg, and multiply that by the % left. - eta := time.Unix(((int64(runTime)/int64(report.Percentage))*int64(pctToGo))+curTime.Unix(), 1).UTC() - // Cap the ETA at 1 year out to prevent providing nonsensical ETAs. - if eta.Before(time.Now().UTC().AddDate(1, 0, 0)) { - report.ETA = eta.Format(vdiff.TimestampFormat) - } - } - return report -} - func commandShow(cmd *cobra.Command, args []string) error { format, err := common.GetOutputFormat(cmd) if err != nil { diff --git a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go index 8fbff03433d..cf713d79579 100644 --- a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go +++ b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go @@ -19,7 +19,6 @@ package vdiff import ( "context" "fmt" - "math" "testing" "time" @@ -681,6 +680,75 @@ func TestVDiffSharded(t *testing.T) { } } +func TestVDiffTextTemplate(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + env := newTestVDiffEnv(t, ctx, []string{"0"}, []string{"0"}, "", nil) + defer env.close() + + now := time.Now() + UUID := uuid.New().String() + req := &tabletmanagerdatapb.VDiffRequest{ + Keyspace: env.targetKeyspace, + Workflow: env.workflow, + Action: string(vdiff.ShowAction), + ActionArg: UUID, + } + starttime := now.UTC().Format(vdiff.TimestampFormat) + + testCases := []struct { + id string + res *sqltypes.Result + report string + }{{ + id: "1", + res: sqltypes.MakeTestResult(fields, + "started||t1|"+UUID+"|started|300|"+starttime+"|30||0|"+ + `{"TableName": "t1", "MatchingRows": 30, "ProcessedRows": 30, "MismatchedRows": 0, "ExtraRowsSource": 0, `+ + `"ExtraRowsTarget": 0}`), + report: fmt.Sprintf(` +VDiff Summary for targetks.vdiffTest (%s) +State: started +RowsCompared: 30 +HasMismatch: false +StartedAt: %s +Progress: 10.00%%, ETA: %s + +Table t1: + State: started + ProcessedRows: 30 + MatchingRows: 30 + +Use "--format=json" for more detailed output. + +`, UUID, starttime, starttime), + }} + + for _, tc := range testCases { + t.Run(tc.id, func(t *testing.T) { + res := &tabletmanagerdatapb.VDiffResponse{ + Id: 1, + Output: sqltypes.ResultToProto3(tc.res), + } + env.tmc.setVDResults(env.tablets[200].tablet, req, res) + req := &vtctldatapb.VDiffShowRequest{ + TargetKeyspace: env.targetKeyspace, + Workflow: env.workflow, + Arg: UUID, + } + + resp, err := env.ws.VDiffShow(context.Background(), req) + require.NoError(t, err) + vds, err := displayShowSingleSummary(env.out, "text", env.targetKeyspace, env.workflow, UUID, resp, true) + require.NoError(t, err) + require.Equal(t, vdiff.StartedState, vds) + + require.Equal(t, tc.report, env.getOutput()) + env.resetOutput() + }) + } +} + func TestGetStructNames(t *testing.T) { type s struct { A string @@ -690,112 +758,3 @@ func TestGetStructNames(t *testing.T) { want := []string{"A", "B"} require.EqualValues(t, want, got) } - -func TestBuildProgressReport(t *testing.T) { - now := time.Now() - type args struct { - summary *summary - rowsToCompare int64 - } - tests := []struct { - name string - args args - want *vdiff.ProgressReport - }{ - { - name: "no progress", - args: args{ - summary: &summary{RowsCompared: 0}, - rowsToCompare: 100, - }, - want: &vdiff.ProgressReport{ - Percentage: 0, - ETA: "", // no ETA - }, - }, - { - name: "one third of the way", - args: args{ - summary: &summary{ - RowsCompared: 33, - StartedAt: now.Add(-10 * time.Second).UTC().Format(vdiff.TimestampFormat), - }, - rowsToCompare: 100, - }, - want: &vdiff.ProgressReport{ - Percentage: 33, - ETA: now.Add(20 * time.Second).UTC().Format(vdiff.TimestampFormat), - }, - }, - { - name: "half way", - args: args{ - summary: &summary{ - RowsCompared: 5000000000, - StartedAt: now.Add(-10 * time.Hour).UTC().Format(vdiff.TimestampFormat), - }, - rowsToCompare: 10000000000, - }, - want: &vdiff.ProgressReport{ - Percentage: 50, - ETA: now.Add(10 * time.Hour).UTC().Format(vdiff.TimestampFormat), - }, - }, - { - name: "full progress", - args: args{ - summary: &summary{ - RowsCompared: 100, - CompletedAt: now.UTC().Format(vdiff.TimestampFormat), - }, - rowsToCompare: 100, - }, - want: &vdiff.ProgressReport{ - Percentage: 100, - ETA: now.UTC().Format(vdiff.TimestampFormat), - }, - }, - { - name: "more than in I_S", - args: args{ - summary: &summary{ - RowsCompared: 100, - CompletedAt: now.UTC().Format(vdiff.TimestampFormat), - }, - rowsToCompare: 50, - }, - want: &vdiff.ProgressReport{ - Percentage: 100, - ETA: now.UTC().Format(vdiff.TimestampFormat), - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tt.args.summary.Progress = BuildProgressReport(tt.args.summary.RowsCompared, tt.args.rowsToCompare, tt.args.summary.StartedAt) - // We always check the percentage - require.Equal(t, int(tt.want.Percentage), int(tt.args.summary.Progress.Percentage)) - - // We only check the ETA if there is one. - if tt.want.ETA != "" { - // Let's check that we're within 1 second to avoid flakes. - wantTime, err := time.Parse(vdiff.TimestampFormat, tt.want.ETA) - require.NoError(t, err) - var timeDiff float64 - if tt.want.Percentage == 100 { - completedTime, err := time.Parse(vdiff.TimestampFormat, tt.args.summary.CompletedAt) - require.NoError(t, err) - timeDiff = math.Abs(completedTime.Sub(wantTime).Seconds()) - } else { - startTime, err := time.Parse(vdiff.TimestampFormat, tt.args.summary.StartedAt) - require.NoError(t, err) - completedTimeUnix := float64(now.UTC().Unix()-startTime.UTC().Unix()) * (100 / tt.want.Percentage) - estimatedTime, err := time.Parse(vdiff.TimestampFormat, tt.want.ETA) - require.NoError(t, err) - timeDiff = math.Abs(estimatedTime.Sub(startTime).Seconds() - completedTimeUnix) - } - require.LessOrEqual(t, timeDiff, 1.0) - } - }) - } -} diff --git a/go/cmd/vtctldclient/command/vreplication/workflow/state.go b/go/cmd/vtctldclient/command/vreplication/workflow/state.go index c10e50f403c..1b934488f58 100644 --- a/go/cmd/vtctldclient/command/vreplication/workflow/state.go +++ b/go/cmd/vtctldclient/command/vreplication/workflow/state.go @@ -60,14 +60,17 @@ func commandUpdateState(cmd *cobra.Command, args []string) error { cli.FinishedParsing(cmd) var state binlogdatapb.VReplicationWorkflowState + var shards []string switch strings.ToLower(cmd.Name()) { case "start": if err := common.CanRestartWorkflow(baseOptions.Keyspace, baseOptions.Workflow); err != nil { return err } state = binlogdatapb.VReplicationWorkflowState_Running + shards = baseOptions.Shards case "stop": state = binlogdatapb.VReplicationWorkflowState_Stopped + shards = baseOptions.Shards default: return fmt.Errorf("invalid workflow state: %s", args[0]) } @@ -80,6 +83,7 @@ func commandUpdateState(cmd *cobra.Command, args []string) error { Cells: textutil.SimulatedNullStringSlice, TabletTypes: textutil.SimulatedNullTabletTypeSlice, State: &state, + Shards: shards, }, } diff --git a/go/cmd/vtctldclient/main.go b/go/cmd/vtctldclient/main.go index a9add98f822..4f31204ca8c 100644 --- a/go/cmd/vtctldclient/main.go +++ b/go/cmd/vtctldclient/main.go @@ -29,6 +29,8 @@ import ( "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vtctl/grpcclientcommon" "vitess.io/vitess/go/vt/vtctl/vtctlclient" + "vitess.io/vitess/go/vt/vttablet/grpctmclient" + "vitess.io/vitess/go/vt/vttablet/tmclient" _flag "vitess.io/vitess/go/internal/flag" ) @@ -44,6 +46,8 @@ func main() { grpcclient.RegisterFlags(command.Root.PersistentFlags()) grpccommon.RegisterFlags(command.Root.PersistentFlags()) grpcclientcommon.RegisterFlags(command.Root.PersistentFlags()) + grpctmclient.RegisterFlags(command.Root.PersistentFlags()) + tmclient.RegisterFlags(command.Root.PersistentFlags()) servenv.RegisterMySQLServerFlags(command.Root.PersistentFlags()) vtctlclient.RegisterFlags(command.Root.PersistentFlags()) acl.RegisterFlags(command.Root.PersistentFlags()) diff --git a/go/cmd/vtctldclient/plugin_grpctmclient.go b/go/cmd/vtctldclient/plugin_grpctmclient.go new file mode 100644 index 00000000000..890562ddc1a --- /dev/null +++ b/go/cmd/vtctldclient/plugin_grpctmclient.go @@ -0,0 +1,28 @@ +/* +Copyright 2025 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 main + +// Imports and registers the gRPC tabletmanager client. +// This is needed when --server=internal as the vtctldclient +// binary will then not only need to talk to the topo server +// directly but it will also need to talk to tablets directly +// via tmclient. + +import ( + _ "vitess.io/vitess/go/vt/vttablet/grpctmclient" + _ "vitess.io/vitess/go/vt/vttablet/tmclient" +) diff --git a/go/flags/endtoend/mysqlctl.txt b/go/flags/endtoend/mysqlctl.txt index 2b179496fff..f803b393a76 100644 --- a/go/flags/endtoend/mysqlctl.txt +++ b/go/flags/endtoend/mysqlctl.txt @@ -71,7 +71,7 @@ Flags: --logtostderr log to standard error instead of files --max-stack-size int configure the maximum stack size in bytes (default 67108864) --mysql_port int MySQL port. (default 3306) - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --mysql_socket string Path to the mysqld socket file. --mysqlctl_client_protocol string the protocol to use to talk to the mysqlctl server (default "grpc") --mysqlctl_mycnf_template string template file to use for generating the my.cnf file during server init diff --git a/go/flags/endtoend/mysqlctld.txt b/go/flags/endtoend/mysqlctld.txt index 594329ce073..22c5f37d63f 100644 --- a/go/flags/endtoend/mysqlctld.txt +++ b/go/flags/endtoend/mysqlctld.txt @@ -99,7 +99,7 @@ Flags: --logtostderr log to standard error instead of files --max-stack-size int configure the maximum stack size in bytes (default 67108864) --mysql_port int MySQL port (default 3306) - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --mysql_socket string Path to the mysqld socket file --mysqlctl_mycnf_template string template file to use for generating the my.cnf file during server init --mysqlctl_socket string socket file to use for remote mysqlctl actions (empty for local actions) diff --git a/go/flags/endtoend/vtbackup.txt b/go/flags/endtoend/vtbackup.txt index bf3a9eb9690..7941ce161ff 100644 --- a/go/flags/endtoend/vtbackup.txt +++ b/go/flags/endtoend/vtbackup.txt @@ -184,7 +184,7 @@ Flags: --mysql-shell-speedup-restore speed up restore by disabling redo logging and double write buffer during the restore process --mysql-shutdown-timeout duration how long to wait for mysqld shutdown (default 5m0s) --mysql_port int mysql port (default 3306) - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --mysql_socket string path to the mysql socket --mysql_timeout duration how long to wait for mysqld startup (default 5m0s) --opentsdb_uri string URI of opentsdb /api/put method @@ -195,6 +195,7 @@ Flags: --remote_operation_timeout duration time to wait for a remote operation (default 15s) --restart_before_backup Perform a mysqld clean/full restart after applying binlogs, but before taking the backup. Only makes sense to work around xtrabackup bugs. --s3_backup_aws_endpoint string endpoint of the S3 backend (region must be provided). + --s3_backup_aws_min_partsize int Minimum part size to use, defaults to 5MiB but can be increased due to the dataset size. (default 5242880) --s3_backup_aws_region string AWS region to use. (default "us-east-1") --s3_backup_aws_retries int AWS request retries. (default -1) --s3_backup_force_path_style force the s3 path style. @@ -231,6 +232,7 @@ Flags: --topo_global_root string the path of the global topology data in the global topology server --topo_global_server_address string the address of the global topology server --topo_implementation string the topology implementation to use + --topo_read_concurrency int Maximum concurrency of topo reads per global or local cell. (default 32) --topo_zk_auth_file string auth to use when connecting to the zk topo server, file contents should be :, e.g., digest:user:pass --topo_zk_base_timeout duration zk base timeout (see zk.Connect) (default 30s) --topo_zk_max_concurrency int maximum number of pending requests to send to a Zookeeper server. (default 64) diff --git a/go/flags/endtoend/vtbench.txt b/go/flags/endtoend/vtbench.txt index 260451f6b03..7b0d72af429 100644 --- a/go/flags/endtoend/vtbench.txt +++ b/go/flags/endtoend/vtbench.txt @@ -69,7 +69,7 @@ Flags: --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) --logtostderr log to standard error instead of files - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --port int VTGate port --pprof strings enable profiling --pprof-http enable pprof http endpoints diff --git a/go/flags/endtoend/vtclient.txt b/go/flags/endtoend/vtclient.txt index 57ddf892ac8..6c0a87d6551 100644 --- a/go/flags/endtoend/vtclient.txt +++ b/go/flags/endtoend/vtclient.txt @@ -35,7 +35,7 @@ Flags: --logtostderr log to standard error instead of files --max_sequence_id int max sequence ID. --min_sequence_id int min sequence ID to generate. When max_sequence_id > min_sequence_id, for each query, a number is generated in [min_sequence_id, max_sequence_id) and attached to the end of the bind variables. - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --parallel int DMLs only: Number of threads executing the same query in parallel. Useful for simple load testing. (default 1) --pprof strings enable profiling --pprof-http enable pprof http endpoints diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index c10d045ecbd..3ae0cbc9b77 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -22,15 +22,7 @@ Flags: --backup_storage_number_blocks int if backup_storage_compress is true, backup_storage_number_blocks sets the number of blocks that can be processed, in parallel, before the writer blocks, during compression (default is 2). It should be equal to the number of CPUs available for compression. (default 2) --bind-address string Bind address for the server. If empty, the server will listen on all available unicast and anycast IP addresses of the local system. --binlog-in-memory-decompressor-max-size uint This value sets the uncompressed transaction payload size at which we switch from in-memory buffer based decompression to the slower streaming mode. (default 134217728) - --binlog_host string PITR restore parameter: hostname/IP of binlog server. - --binlog_password string PITR restore parameter: password of binlog server. --binlog_player_protocol string the protocol to download binlogs from a vttablet (default "grpc") - --binlog_port int PITR restore parameter: port of binlog server. - --binlog_ssl_ca string PITR restore parameter: Filename containing TLS CA certificate to verify binlog server TLS certificate against. - --binlog_ssl_cert string PITR restore parameter: Filename containing mTLS client certificate to present to binlog server as authentication. - --binlog_ssl_key string PITR restore parameter: Filename containing mTLS client private key for use in binlog server authentication. - --binlog_ssl_server_name string PITR restore parameter: TLS server name (common name) to verify against for the binlog server we are connecting to (If not set: use the hostname or IP supplied in --binlog_host). - --binlog_user string PITR restore parameter: username of binlog server. --buffer_drain_concurrency int Maximum number of requests retried simultaneously. More concurrency will increase the load on the PRIMARY vttablet when draining the buffer. (default 1) --buffer_keyspace_shards string If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable_buffer=true. --buffer_max_failover_duration duration Stop buffering completely if a failover takes longer than this duration. (default 20s) @@ -52,6 +44,7 @@ Flags: --config-path strings Paths to search for config files in. (default [{{ .Workdir }}]) --config-persistence-min-interval duration minimum interval between persisting dynamic config changes back to disk (if no change has occurred, nothing is done). (default 1s) --config-type string Config file type (omit to infer config type from file extension). + --consolidator-query-waiter-cap int Configure the maximum number of clients allowed to wait on the consolidator. --consolidator-stream-query-size int Configure the stream consolidator query size in bytes. Setting to 0 disables the stream consolidator. (default 2097152) --consolidator-stream-total-size int Configure the stream consolidator total size in bytes. Setting to 0 disables the stream consolidator. (default 134217728) --consul_auth_static_file string JSON File to read the topos/tokens from. @@ -110,13 +103,16 @@ Flags: --ddl_strategy string Set default strategy for DDL statements. Override with @@ddl_strategy session variable (default "direct") --default_tablet_type topodatapb.TabletType The default tablet type to set for queries, when one is not explicitly selected. (default PRIMARY) --degraded_threshold duration replication lag after which a replica is considered degraded (default 30s) + --disk-write-dir string if provided, tablet will attempt to write a file to this directory to check if the disk is stalled + --disk-write-interval duration how often to write to the disk to check whether it is stalled (default 5s) + --disk-write-timeout duration if writes exceed this duration, the disk is considered stalled (default 30s) --emit_stats If set, emit stats to push-based monitoring and stats backends --enable-consolidator Synonym to -enable_consolidator (default true) --enable-consolidator-replicas Synonym to -enable_consolidator_replicas --enable-partial-keyspace-migration (Experimental) Follow shard routing rules: enable only while migrating a keyspace shard by shard. See documentation on Partial MoveTables for more. (default false) --enable-per-workload-table-metrics If true, query counts and query error metrics include a label that identifies the workload --enable-tx-throttler Synonym to -enable_tx_throttler - --enable-views Enable views support in vtgate. + --enable-views Enable views support in vtgate. (default true) --enable_buffer Enable buffering (stalling) of primary traffic during failovers. --enable_buffer_dry_run Detect and log failover events, but do not actually buffer requests. --enable_consolidator This option enables the query consolidator. (default true) @@ -250,7 +246,7 @@ Flags: --mysql_server_ssl_key string Path to ssl key for mysql server plugin SSL --mysql_server_ssl_server_ca string path to server CA in PEM format, which will be combine with server cert, return full certificate chain to clients --mysql_server_tls_min_version string Configures the minimal TLS version negotiated when SSL is enabled. Defaults to TLSv1.2. Options: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3. - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --mysql_server_write_timeout duration connection write timeout --mysql_slow_connect_warn_threshold duration Warn if it takes more than the given threshold for a mysql connection to establish --mysql_tcp_version string Select tcp, tcp4, or tcp6 to control the socket type. (default "tcp") @@ -261,7 +257,6 @@ Flags: --onclose_timeout duration wait no more than this for OnClose handlers before stopping (default 10s) --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --pid_file string If set, the process will write its pid to the named file, and delete it on graceful shutdown. - --pitr_gtid_lookup_timeout duration PITR restore parameter: timeout for fetching gtid from timestamp. (default 1m0s) --planner-version string Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right --pool_hostname_resolve_interval duration if set force an update to all hostnames and reconnect if changed, defaults to 0 (disabled) --port int port for the server @@ -278,6 +273,7 @@ Flags: --querylog-buffer-size int Maximum number of buffered query logs before throttling log output (default 10) --querylog-filter-tag string string that must be present in the query for it to be logged; if using a value as the tag, you need to disable query normalization --querylog-format string format for query logs ("text" or "json") (default "text") + --querylog-mode string Mode for logging queries. "error" will only log queries that return an error. Otherwise all queries will be logged. (default "all") --querylog-row-threshold uint Number of rows a query has to return or affect before being logged; not useful for streaming queries. 0 means all queries will be logged. --querylog-sample-rate float Sample rate for logging queries. Value must be between 0.0 (no logging) and 1.0 (all queries) --queryserver-config-acl-exempt-acl string an acl that exempt from table acl checking (this acl is free to access any vitess tables). @@ -291,11 +287,13 @@ Flags: --queryserver-config-pool-conn-max-lifetime duration query server connection max lifetime, vttablet manages various mysql connection pools. This config means if a connection has lived at least this long, it connection will be removed from pool upon the next time it is returned to the pool. --queryserver-config-pool-size int query server read pool size, connection pool is used by regular queries (non streaming, not in a transaction) (default 16) --queryserver-config-query-cache-memory int query server query cache size in bytes, maximum amount of memory to be used for caching. vttablet analyzes every incoming query and generate a query plan, these plans are being cached in a lru cache. This config controls the capacity of the lru cache. (default 33554432) + --queryserver-config-query-pool-max-idle-count int query server query pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods. --queryserver-config-query-pool-timeout duration query server query pool timeout, it is how long vttablet waits for a connection from the query pool. If set to 0 (default) then the overall query timeout is used instead. --queryserver-config-query-timeout duration query server query timeout, this is the query timeout in vttablet side. If a query takes more than this timeout, it will be killed. (default 30s) --queryserver-config-schema-change-signal query server schema signal, will signal connected vtgates that schema has changed whenever this is detected. VTGates will need to have -schema_change_signal enabled for this to work (default true) --queryserver-config-schema-reload-time duration query server schema reload time, how often vttablet reloads schemas from underlying MySQL instance. vttablet keeps table schemas in its own memory and periodically refreshes it from MySQL. This config controls the reload time. (default 30m0s) --queryserver-config-stream-buffer-size int query server stream buffer size, the maximum number of bytes sent from vttablet for each stream call. It's recommended to keep this value in sync with vtgate's stream_buffer_size. (default 32768) + --queryserver-config-stream-pool-max-idle-count int query server stream pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods. --queryserver-config-stream-pool-size int query server stream connection pool size, stream pool is used by stream queries: queries that return results to client in a streaming fashion (default 200) --queryserver-config-stream-pool-timeout duration query server stream pool timeout, it is how long vttablet waits for a connection from the stream pool. If set to 0 (default) then there is no timeout. --queryserver-config-strict-table-acl only allow queries that pass table acl checks @@ -303,6 +301,7 @@ Flags: --queryserver-config-transaction-cap int query server transaction cap is the maximum number of transactions allowed to happen at any given point of a time for a single vttablet. E.g. by setting transaction cap to 100, there are at most 100 transactions will be processed by a vttablet and the 101th transaction will be blocked (and fail if it cannot get connection within specified timeout) (default 20) --queryserver-config-transaction-timeout duration query server transaction timeout, a transaction will be killed if it takes longer than this value (default 30s) --queryserver-config-truncate-error-len int truncate errors sent to client if they are longer than this value (0 means do not truncate) + --queryserver-config-txpool-max-idle-count int query server transaction pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods. --queryserver-config-txpool-timeout duration query server transaction pool timeout, it is how long vttablet waits if tx pool is full (default 1s) --queryserver-config-warn-result-size int query server result size warning threshold, warn if number of rows returned from vttablet for non-streaming queries exceeds this --queryserver-enable-views Enable views support in vttablet. @@ -374,7 +373,7 @@ Flags: --topo_global_root string the path of the global topology data in the global topology server --topo_global_server_address string the address of the global topology server --topo_implementation string the topology implementation to use - --topo_read_concurrency int Concurrency of topo reads. (default 32) + --topo_read_concurrency int Maximum concurrency of topo reads per global or local cell. (default 32) --topo_zk_auth_file string auth to use when connecting to the zk topo server, file contents should be :, e.g., digest:user:pass --topo_zk_base_timeout duration zk base timeout (see zk.Connect) (default 30s) --topo_zk_max_concurrency int maximum number of pending requests to send to a Zookeeper server. (default 64) @@ -395,8 +394,7 @@ Flags: --transaction_limit_per_user float Maximum number of transactions a single user is allowed to use at any time, represented as fraction of -transaction_cap. (default 0.4) --transaction_mode string SINGLE: disallow multi-db transactions, MULTI: allow multi-db transactions with best effort commit, TWOPC: allow multi-db transactions with 2pc commit (default "MULTI") --truncate-error-len int truncate errors sent to client if they are longer than this value (0 means do not truncate) - --twopc_abandon_age float time in seconds. Any unresolved transaction older than this time will be sent to the coordinator to be resolved. - --twopc_enable if the flag is on, 2pc is enabled. Other 2pc flags must be supplied. + --twopc_abandon_age time.Duration Any unresolved transaction older than this time will be sent to the coordinator to be resolved. NOTE: Providing time as seconds (float64) is deprecated. Use time.Duration format (e.g., '1s', '2m', '1h'). (default 15m0s) --tx-throttler-config string Synonym to -tx_throttler_config (default "target_replication_lag_sec:2 max_replication_lag_sec:10 initial_rate:100 max_increase:1 emergency_decrease:0.5 min_duration_between_increases_sec:40 max_duration_between_increases_sec:62 min_duration_between_decreases_sec:20 spread_backlog_across_sec:20 age_bad_rate_after_sec:180 bad_rate_increase:0.1 max_rate_approach_threshold:0.9") --tx-throttler-default-priority int Default priority assigned to queries that lack priority information (default 100) --tx-throttler-dry-run If present, the transaction throttler only records metrics about requests received and throttled, but does not actually throttle any requests. diff --git a/go/flags/endtoend/vtctld.txt b/go/flags/endtoend/vtctld.txt index 8b1aa6f4a92..764c07a9d69 100644 --- a/go/flags/endtoend/vtctld.txt +++ b/go/flags/endtoend/vtctld.txt @@ -98,7 +98,7 @@ Flags: --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) --logtostderr log to standard error instead of files --max-stack-size int configure the maximum stack size in bytes (default 67108864) - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --onclose_timeout duration wait no more than this for OnClose handlers before stopping (default 10s) --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --opentsdb_uri string URI of opentsdb /api/put method @@ -110,6 +110,7 @@ Flags: --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --remote_operation_timeout duration time to wait for a remote operation (default 15s) --s3_backup_aws_endpoint string endpoint of the S3 backend (region must be provided). + --s3_backup_aws_min_partsize int Minimum part size to use, defaults to 5MiB but can be increased due to the dataset size. (default 5242880) --s3_backup_aws_region string AWS region to use. (default "us-east-1") --s3_backup_aws_retries int AWS request retries. (default -1) --s3_backup_force_path_style force the s3 path style. @@ -164,7 +165,7 @@ Flags: --topo_global_root string the path of the global topology data in the global topology server --topo_global_server_address string the address of the global topology server --topo_implementation string the topology implementation to use - --topo_read_concurrency int Concurrency of topo reads. (default 32) + --topo_read_concurrency int Maximum concurrency of topo reads per global or local cell. (default 32) --topo_zk_auth_file string auth to use when connecting to the zk topo server, file contents should be :, e.g., digest:user:pass --topo_zk_base_timeout duration zk base timeout (see zk.Connect) (default 30s) --topo_zk_max_concurrency int maximum number of pending requests to send to a Zookeeper server. (default 64) diff --git a/go/flags/endtoend/vtctldclient.txt b/go/flags/endtoend/vtctldclient.txt index 5ff2a7b21da..0e0c91fbf7d 100644 --- a/go/flags/endtoend/vtctldclient.txt +++ b/go/flags/endtoend/vtctldclient.txt @@ -1,4 +1,4 @@ -Executes a cluster management command on the remote vtctld server. +Executes a cluster management command on the remote vtctld server or alternatively as a standalone binary using --server=internal. If there are no running vtctld servers -- for example when bootstrapping a new Vitess cluster -- you can specify a --server value of 'internal'. When doing so, you would use the --topo* flags so that the client can @@ -21,6 +21,7 @@ Available Commands: ChangeTabletTags Changes the tablet tags for the specified tablet, if possible. ChangeTabletType Changes the db type for the specified tablet, if possible. CheckThrottler Issue a throttler check on the given tablet. + CopySchemaShard Copies the schema from a source shard's primary (or a specific tablet) to a destination shard. The schema is applied directly on the primary of the destination shard, and it is propagated to the replicas through binlogs. CreateKeyspace Creates the specified keyspace in the topology. CreateShard Creates the specified shard in the topology. DeleteCellInfo Deletes the CellInfo for the provided cell. @@ -104,52 +105,63 @@ Available Commands: VDiff Perform commands related to diffing tables involved in a VReplication workflow between the source and target. Validate Validates that all nodes reachable from the global replication graph, as well as all tablets in discoverable cells, are consistent. ValidateKeyspace Validates that all nodes reachable from the specified keyspace are consistent. - ValidateSchemaKeyspace Validates that the schema on the primary tablet for shard 0 matches the schema on all other tablets in the keyspace. + ValidatePermissionsKeyspace Validates that the permissions on the primary of the first shard match those of all of the other tablets in the keyspace. + ValidatePermissionsShard Validates that the permissions on the primary match all of the replicas. + ValidateSchemaKeyspace Validates that the schema on the primary tablet for the first shard matches the schema on all other tablets in the keyspace. + ValidateSchemaShard Validates that the schema on the primary tablet for the specified shard matches the schema on all other tablets in that shard. ValidateShard Validates that all nodes reachable from the specified shard are consistent. - ValidateVersionKeyspace Validates that the version on the primary tablet of shard 0 matches all of the other tablets in the keyspace. + ValidateVersionKeyspace Validates that the version on the primary tablet of the first shard matches all of the other tablets in the keyspace. ValidateVersionShard Validates that the version on the primary matches all of the replicas. Workflow Administer VReplication workflows (Reshard, MoveTables, etc) in the given keyspace. + WriteTopologyPath Copies a local file to the topology server at the given path. completion Generate the autocompletion script for the specified shell help Help about any command Flags: - --action_timeout duration timeout to use for the command (default 1h0m0s) - --alsologtostderr log to standard error as well as files - --compact use compact format for otherwise verbose outputs - --grpc_auth_static_client_creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server. - --grpc_compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy - --grpc_enable_tracing Enable gRPC tracing. - --grpc_initial_conn_window_size int gRPC initial connection window size - --grpc_initial_window_size int gRPC initial window size - --grpc_keepalive_time duration After a duration of this time, if the client doesn't see any activity, it pings the server to see if the transport is still alive. (default 10s) - --grpc_keepalive_timeout duration After having pinged for keepalive check, the client waits for a duration of Timeout and if no activity is seen even after that the connection is closed. (default 10s) - --grpc_max_message_size int Maximum allowed RPC message size. Larger messages will be rejected by gRPC with the error 'exceeding the max size'. (default 16777216) - --grpc_prometheus Enable gRPC monitoring with Prometheus. - -h, --help help for vtctldclient - --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) - --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace - --log_dir string If non-empty, write log files in this directory - --log_link string If non-empty, add symbolic links in this directory to the log files - --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) - --logbuflevel int Buffer log messages logged at this level or lower (-1 means don't buffer; 0 means buffer INFO only; ...). Has limited applicability on non-prod platforms. - --logtostderr log to standard error instead of files - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") - --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) - --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) - --server string server to use for the connection (required) - --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) - --topo-global-root string the path of the global topology data in the global topology server (default "/vitess/global") - --topo-global-server-address strings the address of the global topology server(s) (default [localhost:2379]) - --topo-implementation string the topology implementation to use (default "etcd2") - -v, --v Level log level for V logs - --version version for vtctldclient - --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging - --vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc") - --vtctld_grpc_ca string the server ca to use to validate servers when connecting - --vtctld_grpc_cert string the cert to use to connect - --vtctld_grpc_crl string the server crl to use to validate server certificates when connecting - --vtctld_grpc_key string the key to use to connect - --vtctld_grpc_server_name string the server name to use to validate server certificate + --action_timeout duration timeout to use for the command (default 1h0m0s) + --alsologtostderr log to standard error as well as files + --compact use compact format for otherwise verbose outputs + --grpc_auth_static_client_creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server. + --grpc_compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy + --grpc_enable_tracing Enable gRPC tracing. + --grpc_initial_conn_window_size int gRPC initial connection window size + --grpc_initial_window_size int gRPC initial window size + --grpc_keepalive_time duration After a duration of this time, if the client doesn't see any activity, it pings the server to see if the transport is still alive. (default 10s) + --grpc_keepalive_timeout duration After having pinged for keepalive check, the client waits for a duration of Timeout and if no activity is seen even after that the connection is closed. (default 10s) + --grpc_max_message_size int Maximum allowed RPC message size. Larger messages will be rejected by gRPC with the error 'exceeding the max size'. (default 16777216) + --grpc_prometheus Enable gRPC monitoring with Prometheus. + -h, --help help for vtctldclient + --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) + --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace + --log_dir string If non-empty, write log files in this directory + --log_link string If non-empty, add symbolic links in this directory to the log files + --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) + --logbuflevel int Buffer log messages logged at this level or lower (-1 means don't buffer; 0 means buffer INFO only; ...). Has limited applicability on non-prod platforms. + --logtostderr log to standard error instead of files + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") + --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) + --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) + --server string server to use for the connection (required) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) + --tablet_manager_grpc_ca string the server ca to use to validate servers when connecting + --tablet_manager_grpc_cert string the cert to use to connect + --tablet_manager_grpc_concurrency int concurrency to use to talk to a vttablet server for performance-sensitive RPCs (like ExecuteFetchAs{Dba,App}, CheckThrottler and FullStatus) (default 8) + --tablet_manager_grpc_crl string the server crl to use to validate server certificates when connecting + --tablet_manager_grpc_key string the key to use to connect + --tablet_manager_grpc_server_name string the server name to use to validate server certificate + --tablet_manager_protocol string Protocol to use to make tabletmanager RPCs to vttablets. (default "grpc") + --topo-global-root string the path of the global topology data in the global topology server (default "/vitess/global") + --topo-global-server-address strings the address of the global topology server(s) (default [localhost:2379]) + --topo-implementation string the topology implementation to use (default "etcd2") + -v, --v Level log level for V logs + --version version for vtctldclient + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging + --vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc") + --vtctld_grpc_ca string the server ca to use to validate servers when connecting + --vtctld_grpc_cert string the cert to use to connect + --vtctld_grpc_crl string the server crl to use to validate server certificates when connecting + --vtctld_grpc_key string the key to use to connect + --vtctld_grpc_server_name string the server name to use to validate server certificate Use "vtctldclient [command] --help" for more information about a command. diff --git a/go/flags/endtoend/vtexplain.txt b/go/flags/endtoend/vtexplain.txt index fdd289e63c7..90013fe1b98 100644 --- a/go/flags/endtoend/vtexplain.txt +++ b/go/flags/endtoend/vtexplain.txt @@ -59,7 +59,7 @@ Flags: --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) --logtostderr log to standard error instead of files - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --normalize Whether to enable vtgate normalization --output-mode string Output in human-friendly text or json (default "text") --planner-version string Sets the default planner to use. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right diff --git a/go/flags/endtoend/vtgate.txt b/go/flags/endtoend/vtgate.txt index 4cb4cd34148..1b3238bca87 100644 --- a/go/flags/endtoend/vtgate.txt +++ b/go/flags/endtoend/vtgate.txt @@ -57,7 +57,7 @@ Flags: --emit_stats If set, emit stats to push-based monitoring and stats backends --enable-balancer Enable the tablet balancer to evenly spread query load for a given tablet type --enable-partial-keyspace-migration (Experimental) Follow shard routing rules: enable only while migrating a keyspace shard by shard. See documentation on Partial MoveTables for more. (default false) - --enable-views Enable views support in vtgate. + --enable-views Enable views support in vtgate. (default true) --enable_buffer Enable buffering (stalling) of primary traffic during failovers. --enable_buffer_dry_run Detect and log failover events, but do not actually buffer requests. --enable_direct_ddl Allow users to submit direct DDL statements (default true) @@ -157,7 +157,7 @@ Flags: --mysql_server_ssl_key string Path to ssl key for mysql server plugin SSL --mysql_server_ssl_server_ca string path to server CA in PEM format, which will be combine with server cert, return full certificate chain to clients --mysql_server_tls_min_version string Configures the minimal TLS version negotiated when SSL is enabled. Defaults to TLSv1.2. Options: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3. - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --mysql_server_write_timeout duration connection write timeout --mysql_slow_connect_warn_threshold duration Warn if it takes more than the given threshold for a mysql connection to establish --mysql_tcp_version string Select tcp, tcp4, or tcp6 to control the socket type. (default "tcp") @@ -177,6 +177,7 @@ Flags: --querylog-buffer-size int Maximum number of buffered query logs before throttling log output (default 10) --querylog-filter-tag string string that must be present in the query for it to be logged; if using a value as the tag, you need to disable query normalization --querylog-format string format for query logs ("text" or "json") (default "text") + --querylog-mode string Mode for logging queries. "error" will only log queries that return an error. Otherwise all queries will be logged. (default "all") --querylog-row-threshold uint Number of rows a query has to return or affect before being logged; not useful for streaming queries. 0 means all queries will be logged. --querylog-sample-rate float Sample rate for logging queries. Value must be between 0.0 (no logging) and 1.0 (all queries) --redact-debug-ui-queries redact full queries and bind variables from debug UI @@ -223,7 +224,7 @@ Flags: --topo_global_root string the path of the global topology data in the global topology server --topo_global_server_address string the address of the global topology server --topo_implementation string the topology implementation to use - --topo_read_concurrency int Concurrency of topo reads. (default 32) + --topo_read_concurrency int Maximum concurrency of topo reads per global or local cell. (default 32) --topo_zk_auth_file string auth to use when connecting to the zk topo server, file contents should be :, e.g., digest:user:pass --topo_zk_base_timeout duration zk base timeout (see zk.Connect) (default 30s) --topo_zk_max_concurrency int maximum number of pending requests to send to a Zookeeper server. (default 64) diff --git a/go/flags/endtoend/vtgateclienttest.txt b/go/flags/endtoend/vtgateclienttest.txt index 8a2f18b6b5a..d5b45e57b1e 100644 --- a/go/flags/endtoend/vtgateclienttest.txt +++ b/go/flags/endtoend/vtgateclienttest.txt @@ -53,7 +53,7 @@ Flags: --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) --logtostderr log to standard error instead of files --max-stack-size int configure the maximum stack size in bytes (default 67108864) - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --onclose_timeout duration wait no more than this for OnClose handlers before stopping (default 10s) --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --pid_file string If set, the process will write its pid to the named file, and delete it on graceful shutdown. diff --git a/go/flags/endtoend/vtorc.txt b/go/flags/endtoend/vtorc.txt index efccb0afdfc..57eb907cf4d 100644 --- a/go/flags/endtoend/vtorc.txt +++ b/go/flags/endtoend/vtorc.txt @@ -24,7 +24,7 @@ Flags: --bind-address string Bind address for the server. If empty, the server will listen on all available unicast and anycast IP addresses of the local system. --catch-sigpipe catch and ignore SIGPIPE on stdout and stderr if specified --change-tablets-with-errant-gtid-to-drained Whether VTOrc should be changing the type of tablets with errant GTIDs to DRAINED - --clusters_to_watch strings Comma-separated list of keyspaces or keyspace/shards that this instance will monitor and repair. Defaults to all clusters in the topology. Example: "ks1,ks2/-80" + --clusters_to_watch strings Comma-separated list of keyspaces or keyspace/keyranges that this instance will monitor and repair. Defaults to all clusters in the topology. Example: "ks1,ks2/-80" --config-file string Full path of the config file (with extension) to use. If set, --config-path, --config-type, and --config-name are ignored. --config-file-not-found-handling ConfigFileNotFoundHandling Behavior when a config file is not found. (Options: error, exit, ignore, warn) (default warn) --config-name string Name of the config file (without extension) to search for. (default "vtconfig") @@ -33,6 +33,7 @@ Flags: --config-type string Config file type (omit to infer config type from file extension). --consul_auth_static_file string JSON File to read the topos/tokens from. --emit_stats If set, emit stats to push-based monitoring and stats backends + --enable-primary-disk-stalled-recovery Whether VTOrc should detect a stalled disk on the primary and failover --grpc-dial-concurrency-limit int Maximum concurrency of grpc dial operations. This should be less than the golang max thread limit of 10000. (default 1024) --grpc_auth_static_client_creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server. --grpc_compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy @@ -98,7 +99,7 @@ Flags: --topo_global_root string the path of the global topology data in the global topology server --topo_global_server_address string the address of the global topology server --topo_implementation string the topology implementation to use - --topo_read_concurrency int Concurrency of topo reads. (default 32) + --topo_read_concurrency int Maximum concurrency of topo reads per global or local cell. (default 32) --topo_zk_auth_file string auth to use when connecting to the zk topo server, file contents should be :, e.g., digest:user:pass --topo_zk_base_timeout duration zk base timeout (see zk.Connect) (default 30s) --topo_zk_max_concurrency int maximum number of pending requests to send to a Zookeeper server. (default 64) diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt index f79db05f327..0a9a0ef99ce 100644 --- a/go/flags/endtoend/vttablet.txt +++ b/go/flags/endtoend/vttablet.txt @@ -57,20 +57,12 @@ Flags: --backup_storage_number_blocks int if backup_storage_compress is true, backup_storage_number_blocks sets the number of blocks that can be processed, in parallel, before the writer blocks, during compression (default is 2). It should be equal to the number of CPUs available for compression. (default 2) --bind-address string Bind address for the server. If empty, the server will listen on all available unicast and anycast IP addresses of the local system. --binlog-in-memory-decompressor-max-size uint This value sets the uncompressed transaction payload size at which we switch from in-memory buffer based decompression to the slower streaming mode. (default 134217728) - --binlog_host string PITR restore parameter: hostname/IP of binlog server. - --binlog_password string PITR restore parameter: password of binlog server. --binlog_player_grpc_ca string the server ca to use to validate servers when connecting --binlog_player_grpc_cert string the cert to use to connect --binlog_player_grpc_crl string the server crl to use to validate server certificates when connecting --binlog_player_grpc_key string the key to use to connect --binlog_player_grpc_server_name string the server name to use to validate server certificate --binlog_player_protocol string the protocol to download binlogs from a vttablet (default "grpc") - --binlog_port int PITR restore parameter: port of binlog server. - --binlog_ssl_ca string PITR restore parameter: Filename containing TLS CA certificate to verify binlog server TLS certificate against. - --binlog_ssl_cert string PITR restore parameter: Filename containing mTLS client certificate to present to binlog server as authentication. - --binlog_ssl_key string PITR restore parameter: Filename containing mTLS client private key for use in binlog server authentication. - --binlog_ssl_server_name string PITR restore parameter: TLS server name (common name) to verify against for the binlog server we are connecting to (If not set: use the hostname or IP supplied in --binlog_host). - --binlog_user string PITR restore parameter: username of binlog server. --builtinbackup-file-read-buffer-size uint read files using an IO buffer of this many bytes. Golang defaults are used when set to 0. --builtinbackup-file-write-buffer-size uint write files using an IO buffer of this many bytes. Golang defaults are used when set to 0. (default 2097152) --builtinbackup-incremental-restore-path string the directory where incremental restore files, namely binlog files, are extracted to. In k8s environments, this should be set to a directory that is shared between the vttablet and mysqld pods. The path should exist. When empty, the default OS temp dir is assumed. @@ -86,6 +78,7 @@ Flags: --config-path strings Paths to search for config files in. (default [{{ .Workdir }}]) --config-persistence-min-interval duration minimum interval between persisting dynamic config changes back to disk (if no change has occurred, nothing is done). (default 1s) --config-type string Config file type (omit to infer config type from file extension). + --consolidator-query-waiter-cap int Configure the maximum number of clients allowed to wait on the consolidator. --consolidator-stream-query-size int Configure the stream consolidator query size in bytes. Setting to 0 disables the stream consolidator. (default 2097152) --consolidator-stream-total-size int Configure the stream consolidator total size in bytes. Setting to 0 disables the stream consolidator. (default 134217728) --consul_auth_static_file string JSON File to read the topos/tokens from. @@ -141,6 +134,9 @@ Flags: --dba_idle_timeout duration Idle timeout for dba connections (default 1m0s) --dba_pool_size int Size of the connection pool for dba connections (default 20) --degraded_threshold duration replication lag after which a replica is considered degraded (default 30s) + --disk-write-dir string if provided, tablet will attempt to write a file to this directory to check if the disk is stalled + --disk-write-interval duration how often to write to the disk to check whether it is stalled (default 5s) + --disk-write-timeout duration if writes exceed this duration, the disk is considered stalled (default 30s) --emit_stats If set, emit stats to push-based monitoring and stats backends --enable-consolidator Synonym to -enable_consolidator (default true) --enable-consolidator-replicas Synonym to -enable_consolidator_replicas @@ -252,14 +248,13 @@ Flags: --mysql-shell-should-drain decide if we should drain while taking a backup or continue to serving traffic --mysql-shell-speedup-restore speed up restore by disabling redo logging and double write buffer during the restore process --mysql-shutdown-timeout duration timeout to use when MySQL is being shut down. (default 5m0s) - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --mysqlctl_mycnf_template string template file to use for generating the my.cnf file during server init --mysqlctl_socket string socket file to use for remote mysqlctl actions (empty for local actions) --onclose_timeout duration wait no more than this for OnClose handlers before stopping (default 10s) --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --opentsdb_uri string URI of opentsdb /api/put method --pid_file string If set, the process will write its pid to the named file, and delete it on graceful shutdown. - --pitr_gtid_lookup_timeout duration PITR restore parameter: timeout for fetching gtid from timestamp. (default 1m0s) --pool_hostname_resolve_interval duration if set force an update to all hostnames and reconnect if changed, defaults to 0 (disabled) --port int port for the server --pprof strings enable profiling @@ -270,6 +265,7 @@ Flags: --query-log-stream-handler string URL handler for streaming queries log (default "/debug/querylog") --querylog-filter-tag string string that must be present in the query for it to be logged; if using a value as the tag, you need to disable query normalization --querylog-format string format for query logs ("text" or "json") (default "text") + --querylog-mode string Mode for logging queries. "error" will only log queries that return an error. Otherwise all queries will be logged. (default "all") --querylog-row-threshold uint Number of rows a query has to return or affect before being logged; not useful for streaming queries. 0 means all queries will be logged. --querylog-sample-rate float Sample rate for logging queries. Value must be between 0.0 (no logging) and 1.0 (all queries) --queryserver-config-acl-exempt-acl string an acl that exempt from table acl checking (this acl is free to access any vitess tables). @@ -283,11 +279,13 @@ Flags: --queryserver-config-pool-conn-max-lifetime duration query server connection max lifetime, vttablet manages various mysql connection pools. This config means if a connection has lived at least this long, it connection will be removed from pool upon the next time it is returned to the pool. --queryserver-config-pool-size int query server read pool size, connection pool is used by regular queries (non streaming, not in a transaction) (default 16) --queryserver-config-query-cache-memory int query server query cache size in bytes, maximum amount of memory to be used for caching. vttablet analyzes every incoming query and generate a query plan, these plans are being cached in a lru cache. This config controls the capacity of the lru cache. (default 33554432) + --queryserver-config-query-pool-max-idle-count int query server query pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods. --queryserver-config-query-pool-timeout duration query server query pool timeout, it is how long vttablet waits for a connection from the query pool. If set to 0 (default) then the overall query timeout is used instead. --queryserver-config-query-timeout duration query server query timeout, this is the query timeout in vttablet side. If a query takes more than this timeout, it will be killed. (default 30s) --queryserver-config-schema-change-signal query server schema signal, will signal connected vtgates that schema has changed whenever this is detected. VTGates will need to have -schema_change_signal enabled for this to work (default true) --queryserver-config-schema-reload-time duration query server schema reload time, how often vttablet reloads schemas from underlying MySQL instance. vttablet keeps table schemas in its own memory and periodically refreshes it from MySQL. This config controls the reload time. (default 30m0s) --queryserver-config-stream-buffer-size int query server stream buffer size, the maximum number of bytes sent from vttablet for each stream call. It's recommended to keep this value in sync with vtgate's stream_buffer_size. (default 32768) + --queryserver-config-stream-pool-max-idle-count int query server stream pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods. --queryserver-config-stream-pool-size int query server stream connection pool size, stream pool is used by stream queries: queries that return results to client in a streaming fashion (default 200) --queryserver-config-stream-pool-timeout duration query server stream pool timeout, it is how long vttablet waits for a connection from the stream pool. If set to 0 (default) then there is no timeout. --queryserver-config-strict-table-acl only allow queries that pass table acl checks @@ -295,6 +293,7 @@ Flags: --queryserver-config-transaction-cap int query server transaction cap is the maximum number of transactions allowed to happen at any given point of a time for a single vttablet. E.g. by setting transaction cap to 100, there are at most 100 transactions will be processed by a vttablet and the 101th transaction will be blocked (and fail if it cannot get connection within specified timeout) (default 20) --queryserver-config-transaction-timeout duration query server transaction timeout, a transaction will be killed if it takes longer than this value (default 30s) --queryserver-config-truncate-error-len int truncate errors sent to client if they are longer than this value (0 means do not truncate) + --queryserver-config-txpool-max-idle-count int query server transaction pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods. --queryserver-config-txpool-timeout duration query server transaction pool timeout, it is how long vttablet waits if tx pool is full (default 1s) --queryserver-config-warn-result-size int query server result size warning threshold, warn if number of rows returned from vttablet for non-streaming queries exceeds this --queryserver-enable-views Enable views support in vttablet. @@ -312,6 +311,7 @@ Flags: --restore_from_backup_ts string (init restore parameter) if set, restore the latest backup taken at or before this timestamp. Example: '2021-04-29.133050' --retain_online_ddl_tables duration How long should vttablet keep an old migrated table before purging it (default 24h0m0s) --s3_backup_aws_endpoint string endpoint of the S3 backend (region must be provided). + --s3_backup_aws_min_partsize int Minimum part size to use, defaults to 5MiB but can be increased due to the dataset size. (default 5242880) --s3_backup_aws_region string AWS region to use. (default "us-east-1") --s3_backup_aws_retries int AWS request retries. (default -1) --s3_backup_force_path_style force the s3 path style. @@ -376,6 +376,7 @@ Flags: --topo_global_root string the path of the global topology data in the global topology server --topo_global_server_address string the address of the global topology server --topo_implementation string the topology implementation to use + --topo_read_concurrency int Maximum concurrency of topo reads per global or local cell. (default 32) --topo_zk_auth_file string auth to use when connecting to the zk topo server, file contents should be :, e.g., digest:user:pass --topo_zk_base_timeout duration zk base timeout (see zk.Connect) (default 30s) --topo_zk_max_concurrency int maximum number of pending requests to send to a Zookeeper server. (default 64) @@ -395,8 +396,7 @@ Flags: --transaction_limit_by_subcomponent Include CallerID.subcomponent when considering who the user is for the purpose of transaction limit. --transaction_limit_by_username Include VTGateCallerID.username when considering who the user is for the purpose of transaction limit. (default true) --transaction_limit_per_user float Maximum number of transactions a single user is allowed to use at any time, represented as fraction of -transaction_cap. (default 0.4) - --twopc_abandon_age float time in seconds. Any unresolved transaction older than this time will be sent to the coordinator to be resolved. - --twopc_enable if the flag is on, 2pc is enabled. Other 2pc flags must be supplied. + --twopc_abandon_age time.Duration Any unresolved transaction older than this time will be sent to the coordinator to be resolved. NOTE: Providing time as seconds (float64) is deprecated. Use time.Duration format (e.g., '1s', '2m', '1h'). (default 15m0s) --tx-throttler-config string Synonym to -tx_throttler_config (default "target_replication_lag_sec:2 max_replication_lag_sec:10 initial_rate:100 max_increase:1 emergency_decrease:0.5 min_duration_between_increases_sec:40 max_duration_between_increases_sec:62 min_duration_between_decreases_sec:20 spread_backlog_across_sec:20 age_bad_rate_after_sec:180 bad_rate_increase:0.1 max_rate_approach_threshold:0.9") --tx-throttler-default-priority int Default priority assigned to queries that lack priority information (default 100) --tx-throttler-dry-run If present, the transaction throttler only records metrics about requests received and throttled, but does not actually throttle any requests. diff --git a/go/flags/endtoend/vttestserver.txt b/go/flags/endtoend/vttestserver.txt index 042ffd37643..385b7194652 100644 --- a/go/flags/endtoend/vttestserver.txt +++ b/go/flags/endtoend/vttestserver.txt @@ -96,7 +96,7 @@ Flags: --mysql-shell-speedup-restore speed up restore by disabling redo logging and double write buffer during the restore process --mysql_bind_host string which host to bind vtgate mysql listener to (default "localhost") --mysql_only If this flag is set only mysql is initialized. The rest of the vitess components are not started. Also, the output specifies the mysql unix socket instead of the vtgate port. - --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") + --mysql_server_version string MySQL server version to advertise. (default "8.0.40-Vitess") --mysqlctl_mycnf_template string template file to use for generating the my.cnf file during server init --mysqlctl_socket string socket file to use for remote mysqlctl actions (empty for local actions) --no_scatter when set to true, the planner will fail instead of producing a plan that includes scatter queries diff --git a/go/flagutil/float_to_duration.go b/go/flagutil/float_to_duration.go new file mode 100644 index 00000000000..fe07d42bfaa --- /dev/null +++ b/go/flagutil/float_to_duration.go @@ -0,0 +1,71 @@ +/* +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 flagutil + +import ( + "errors" + "strconv" + "time" + + "github.com/spf13/pflag" +) + +// FloatOrDuration is a flag that can be set with either a float64 (interpreted as seconds) or a time.Duration +// The parsed value is stored in the Duration field, and the target pointer is updated with the parsed value +type FloatOrDuration struct { + Target *time.Duration // Pointer to the external duration + Duration time.Duration // Stores the current parsed value +} + +// String returns the current value as a string +func (f *FloatOrDuration) String() string { + return f.Duration.String() +} + +// Set parses the input and updates the duration +func (f *FloatOrDuration) Set(value string) error { + // Try to parse as float64 first (interpreted as seconds) + if floatVal, err := strconv.ParseFloat(value, 64); err == nil { + f.Duration = time.Duration(floatVal * float64(time.Second)) + *f.Target = f.Duration // Update the target pointer + return nil + } + + // Try to parse as time.Duration + if duration, err := time.ParseDuration(value); err == nil { + f.Duration = duration + *f.Target = f.Duration // Update the target pointer + return nil + } + + return errors.New("value must be either a float64 (interpreted as seconds) or a valid time.Duration") +} + +// Type returns the type description +func (f *FloatOrDuration) Type() string { + return "time.Duration" +} + +// FloatDuration defines a flag with the specified name, default value, and usage string and binds it to a time.Duration variable. +func FloatDuration(fs *pflag.FlagSet, p *time.Duration, name string, defaultValue time.Duration, usage string) { + *p = defaultValue + fd := FloatOrDuration{ + Target: p, + Duration: defaultValue, + } + fs.Var(&fd, name, usage) +} diff --git a/go/flagutil/float_to_duration_test.go b/go/flagutil/float_to_duration_test.go new file mode 100644 index 00000000000..50b3a36e94a --- /dev/null +++ b/go/flagutil/float_to_duration_test.go @@ -0,0 +1,104 @@ +/* +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 flagutil + +import ( + "testing" + "time" + + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" +) + +// TestFloatOrDuration_ValidFloat64Input verifies that a float64 input +// (representing seconds) is correctly converted to a time.Duration. +func TestFloatOrDuration_ValidFloat64Input(t *testing.T) { + var duration time.Duration + fs := pflag.NewFlagSet("test", pflag.ContinueOnError) + + FloatDuration(fs, &duration, "test_flag", 10*time.Second, "Test flag") + err := fs.Parse([]string{"--test_flag=2"}) + assert.NoError(t, err) + assert.Equal(t, 2*time.Second, duration) +} + +// TestFloatOrDuration_ValidDurationInput verifies that a valid time.Duration +// input (e.g., "1m30s") is parsed and stored correctly. +func TestFloatOrDuration_ValidDurationInput(t *testing.T) { + var duration time.Duration + fs := pflag.NewFlagSet("test", pflag.ContinueOnError) + + FloatDuration(fs, &duration, "test_flag", 10*time.Second, "Test flag") + err := fs.Parse([]string{"--test_flag=1m30s"}) + assert.NoError(t, err) + assert.Equal(t, 90*time.Second, duration) +} + +// TestFloatOrDuration_DefaultValue ensures that the default value is correctly +// assigned to the duration when the flag is not provided. +func TestFloatOrDuration_DefaultValue(t *testing.T) { + var duration time.Duration + fs := pflag.NewFlagSet("test", pflag.ContinueOnError) + + defaultValue := 15 * time.Second + FloatDuration(fs, &duration, "test_flag", defaultValue, "Test flag") + err := fs.Parse([]string{}) + assert.NoError(t, err) + assert.Equal(t, defaultValue, duration) +} + +// TestFloatOrDuration_InvalidInput verifies that an invalid input string +// results in an appropriate error. +func TestFloatOrDuration_InvalidInput(t *testing.T) { + var duration time.Duration + fs := pflag.NewFlagSet("test", pflag.ContinueOnError) + + FloatDuration(fs, &duration, "test_flag", 10*time.Second, "Test flag") + err := fs.Parse([]string{"--test_flag=invalid"}) + assert.Error(t, err) + assert.Contains(t, err.Error(), "value must be either a float64 (interpreted as seconds) or a valid time.Duration") +} + +// TestFloatOrDuration_MultipleFlags ensures that multiple FloatDuration flags +// can coexist and maintain independent values. +func TestFloatOrDuration_MultipleFlags(t *testing.T) { + var duration1, duration2 time.Duration + fs := pflag.NewFlagSet("test", pflag.ContinueOnError) + + FloatDuration(fs, &duration1, "flag1", 10*time.Second, "First test flag") + FloatDuration(fs, &duration2, "flag2", 20*time.Second, "Second test flag") + + err := fs.Parse([]string{"--flag1=2.5", "--flag2=1m"}) + assert.NoError(t, err) + assert.Equal(t, 2500*time.Millisecond, duration1) + assert.Equal(t, 1*time.Minute, duration2) +} + +// TestFloatOrDuration_HelpMessage verifies that the help message includes +// the correct flag name, description, and default value. +func TestFloatOrDuration_HelpMessage(t *testing.T) { + var duration time.Duration + fs := pflag.NewFlagSet("test", pflag.ContinueOnError) + + defaultValue := 10 * time.Second + FloatDuration(fs, &duration, "test_flag", defaultValue, "Test flag with default value") + + helpOutput := fs.FlagUsages() + assert.Contains(t, helpOutput, "--test_flag time.Duration") + assert.Contains(t, helpOutput, "Test flag with default value") + assert.Contains(t, helpOutput, "(default 10s)") +} diff --git a/go/mysql/binlog/binlog_json.go b/go/mysql/binlog/binlog_json.go index 03bf604fb2d..51b4fef0ef8 100644 --- a/go/mysql/binlog/binlog_json.go +++ b/go/mysql/binlog/binlog_json.go @@ -17,6 +17,7 @@ limitations under the License. package binlog import ( + "bytes" "encoding/binary" "fmt" "math" @@ -25,9 +26,12 @@ import ( "vitess.io/vitess/go/hack" "vitess.io/vitess/go/mysql/format" "vitess.io/vitess/go/mysql/json" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" ) /* @@ -44,6 +48,14 @@ https://github.com/shyiko/mysql-binlog-connector-java/pull/119/files https://github.com/noplay/python-mysql-replication/blob/175df28cc8b536a68522ff9b09dc5440adad6094/pymysqlreplication/packet.py */ +type jsonDiffOp uint8 + +const ( + jsonDiffOpReplace = jsonDiffOp(iota) + jsonDiffOpInsert + jsonDiffOpRemove +) + // ParseBinaryJSON provides the parsing function from the mysql binary json // representation to a JSON value instance. func ParseBinaryJSON(data []byte) (*json.Value, error) { @@ -60,6 +72,168 @@ func ParseBinaryJSON(data []byte) (*json.Value, error) { return node, nil } +// ParseBinaryJSONDiff provides the parsing function from the binary MySQL +// JSON diff representation to an SQL expression. These diffs are included +// in the AFTER image of PartialUpdateRows events which exist in MySQL 8.0 +// and later when the --binlog-row-value-options=PARTIAL_JSON is used. You +// can read more about these here: +// https://dev.mysql.com/blog-archive/efficient-json-replication-in-mysql-8-0/ +// https://dev.mysql.com/worklog/task/?id=2955 +// https://github.com/mysql/mysql-server/blob/trunk/sql-common/json_diff.h +// https://github.com/mysql/mysql-server/blob/trunk/sql-common/json_diff.cc +// +// The binary format for the partial JSON column or JSON diff is: +// +--------+--------+--------+ +--------+ +// | length | diff_1 | diff_2 | ... | diff_N | +// +--------+--------+--------+ +--------+ +// +// Each diff_i represents a single JSON diff. It has the following +// format: +// +-----------+-------------+------+ +-------------+------+ +// | operation | path_length | path | ( | data_length | data | )? +// +-----------+-------------+------+ +-------------+------+ +// +// The fields are: +// +// 1. operation: a single byte containing the JSON diff operation. +// The possible values are defined by enum_json_diff_operation: +// REPLACE=0 +// INSERT=1 +// REMOVE=2 +// +// 2. path_length: an unsigned integer in net_field_length() format. +// +// 3. path: a string of 'path_length' bytes containing the JSON path +// of the update. +// +// 4. data_length: an unsigned integer in net_field_length() format. +// +// 5. data: a string of 'data_length' bytes containing the JSON +// document that will be inserted at the position specified by +// 'path'. +// +// data_length and data are omitted if and only if operation=REMOVE. +// +// Examples of the resulting SQL expression are: +// - "" for an empty diff when the column was not updated +// - "null" for a JSON null +// - "JSON_REMOVE(%s, _utf8mb4'$.salary')" for a REMOVE operation +// - "JSON_INSERT(%s, _utf8mb4'$.role', CAST(JSON_QUOTE(_utf8mb4'manager') as JSON))" for an INSERT operation +// - "JSON_INSERT(JSON_REMOVE(JSON_REPLACE(%s, _utf8mb4'$.day', CAST(JSON_QUOTE(_utf8mb4'tuesday') as JSON)), _utf8mb4'$.favorite_color'), _utf8mb4'$.hobby', CAST(JSON_QUOTE(_utf8mb4'skiing') as JSON))" for a more complex example +func ParseBinaryJSONDiff(data []byte) (sqltypes.Value, error) { + if len(data) == 0 { + // An empty diff is used as a way to elide the column from + // the AFTER image when it was not updated in the row event. + return sqltypes.MakeTrusted(sqltypes.Expression, data), nil + } + + diff := bytes.Buffer{} + // Reasonable estimate of the space we'll need to build the SQL + // expression in order to try and avoid reallocations w/o + // overallocating too much. + diff.Grow(len(data) + 80) + pos := 0 + outer := false + innerStr := "" + + // Create the SQL expression from the data which will consist of + // a sequence of JSON_X(col/json, path[, value]) clauses where X + // is REPLACE, INSERT, or REMOVE. The data can also be a JSON + // null, which is a special case we handle here as well. We take + // a binary representation of a vector of JSON diffs, for example: + // (REPLACE, '$.a', '7') + // (REMOVE, '$.d[0]') + // (INSERT, '$.e', '"ee"') + // (INSERT, '$.f[1]', '"ff"') + // (INSERT, '$.g', '"gg"') + // And build an SQL expression from it: + // JSON_INSERT( + // JSON_INSERT( + // JSON_INSERT( + // JSON_REMOVE( + // JSON_REPLACE( + // col, '$.a', 7), + // '$.d[0]'), + // '$.e', 'ee'), + // '$.f[3]', 'ff'), + // '$.g', 'gg') + for pos < len(data) { + opType := jsonDiffOp(data[pos]) + pos++ + if outer { + // We process the bytes sequentially but build the SQL + // expression from the inner most function to the outer most + // and thus need to wrap any subsequent functions around the + // previous one(s). For example: + // - inner: JSON_REPLACE(%s, '$.a', 7) + // - outer: JSON_REMOVE(, '$.b') + innerStr = diff.String() + diff.Reset() + } + switch opType { + case jsonDiffOpReplace: + diff.WriteString("JSON_REPLACE(") + case jsonDiffOpInsert: + diff.WriteString("JSON_INSERT(") + case jsonDiffOpRemove: + diff.WriteString("JSON_REMOVE(") + default: + // Can be a JSON null. + js, err := ParseBinaryJSON(data) + if err == nil && js.Type() == json.TypeNull { + return sqltypes.MakeTrusted(sqltypes.Expression, js.MarshalSQLTo(nil)), nil + } + return sqltypes.Value{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, + "invalid JSON diff operation: %d", opType) + } + if outer { + // Wrap this outer function around the previous inner one(s). + diff.WriteString(innerStr) + diff.WriteString(", ") + } else { // Only the inner most function has the field name + diff.WriteString("%s, ") // This will later be replaced by the field name + } + outer = true + + // Read the JSON document path that we want to operate on. + pathLen, readTo := readVariableLength(data, pos) + pos = readTo + path := data[pos : pos+pathLen] + pos += pathLen + // We have to specify the unicode character set for the path we + // use in the expression as the connection can be using a different + // character set (e.g. vreplication always uses set names binary). + // The generated path will look like this: _utf8mb4'$.role' + diff.WriteString(sqlparser.Utf8mb4Str) + diff.WriteByte('\'') + diff.Write(path) + diff.WriteByte('\'') + if opType == jsonDiffOpRemove { // No value for remove + diff.WriteByte(')') // Close the JSON function + continue + } + + diff.WriteString(", ") + // Read the value that we want to set. + valueLen, readTo := readVariableLength(data, pos) + pos = readTo + // Parse the native JSON type and its value that we want to set + // (string, number, object, array, null). + value, err := ParseBinaryJSON(data[pos : pos+valueLen]) + if err != nil { + return sqltypes.Value{}, vterrors.Wrapf(err, + "cannot read JSON diff value for path %q", path) + } + pos += valueLen + // Generate the SQL clause for the JSON value. For example: + // CAST(JSON_QUOTE(_utf8mb4'manager') as JSON) + diff.Write(value.MarshalSQLTo(nil)) + diff.WriteByte(')') // Close the JSON function + } + + return sqltypes.MakeTrusted(sqltypes.Expression, diff.Bytes()), nil +} + // jsonDataType has the values used in the mysql json binary representation to denote types. // We have string, literal(true/false/null), number, object or array types. // large object => doc size > 64K: you get pointers instead of inline values. @@ -315,7 +489,7 @@ func binparserOpaque(_ jsonDataType, data []byte, pos int) (node *json.Value, er precision := decimalData[0] scale := decimalData[1] metadata := (uint16(precision) << 8) + uint16(scale) - val, _, err := CellValue(decimalData, 2, TypeNewDecimal, metadata, &querypb.Field{Type: querypb.Type_DECIMAL}) + val, _, err := CellValue(decimalData, 2, TypeNewDecimal, metadata, &querypb.Field{Type: querypb.Type_DECIMAL}, false) if err != nil { return nil, err } diff --git a/go/mysql/binlog/rbr.go b/go/mysql/binlog/rbr.go index 8b95b0daee9..7512413f606 100644 --- a/go/mysql/binlog/rbr.go +++ b/go/mysql/binlog/rbr.go @@ -26,9 +26,10 @@ import ( "time" "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" + + querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) // ZeroTimestamp is the special value 0 for a timestamp. @@ -130,7 +131,7 @@ func CellLength(data []byte, pos int, typ byte, metadata uint16) (int, error) { uint32(data[pos+2])<<16| uint32(data[pos+3])<<24), nil default: - return 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "unsupported blob/geometry metadata value %v (data: %v pos: %v)", metadata, data, pos) + return 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unsupported blob/geometry metadata value %v (data: %v pos: %v)", metadata, data, pos) } case TypeString: // This may do String, Enum, and Set. The type is in @@ -151,7 +152,7 @@ func CellLength(data []byte, pos int, typ byte, metadata uint16) (int, error) { return l + 1, nil default: - return 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "unsupported type %v (data: %v pos: %v)", typ, data, pos) + return 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unsupported type %v (data: %v pos: %v)", typ, data, pos) } } @@ -176,7 +177,7 @@ func printTimestamp(v uint32) *bytes.Buffer { // byte to determine general shared aspects of types and the querypb.Field to // determine other info specifically about its underlying column (SQL column // type, column length, charset, etc) -func CellValue(data []byte, pos int, typ byte, metadata uint16, field *querypb.Field) (sqltypes.Value, int, error) { +func CellValue(data []byte, pos int, typ byte, metadata uint16, field *querypb.Field, partialJSON bool) (sqltypes.Value, int, error) { switch typ { case TypeTiny: if sqltypes.IsSigned(field.Type) { @@ -644,7 +645,7 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, field *querypb.F return sqltypes.MakeTrusted(querypb.Type_ENUM, strconv.AppendUint(nil, uint64(val), 10)), 2, nil default: - return sqltypes.NULL, 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected enum size: %v", metadata&0xff) + return sqltypes.NULL, 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected enum size: %v", metadata&0xff) } case TypeSet: @@ -672,14 +673,20 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, field *querypb.F uint32(data[pos+2])<<16 | uint32(data[pos+3])<<24) default: - return sqltypes.NULL, 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "unsupported blob metadata value %v (data: %v pos: %v)", metadata, data, pos) + return sqltypes.NULL, 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unsupported blob metadata value %v (data: %v pos: %v)", metadata, data, pos) } pos += int(metadata) // For JSON, we parse the data, and emit SQL. if typ == TypeJSON { - var err error jsonData := data[pos : pos+l] + if partialJSON { + val, err := ParseBinaryJSONDiff(jsonData) + if err != nil { + panic(err) + } + return val, l + int(metadata), nil + } jsonVal, err := ParseBinaryJSON(jsonData) if err != nil { panic(err) @@ -710,7 +717,7 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, field *querypb.F return sqltypes.MakeTrusted(querypb.Type_UINT16, strconv.AppendUint(nil, uint64(val), 10)), 2, nil default: - return sqltypes.NULL, 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected enum size: %v", metadata&0xff) + return sqltypes.NULL, 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected enum size: %v", metadata&0xff) } } if t == TypeSet { @@ -776,13 +783,13 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, field *querypb.F uint32(data[pos+2])<<16 | uint32(data[pos+3])<<24) default: - return sqltypes.NULL, 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "unsupported geometry metadata value %v (data: %v pos: %v)", metadata, data, pos) + return sqltypes.NULL, 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unsupported geometry metadata value %v (data: %v pos: %v)", metadata, data, pos) } pos += int(metadata) return sqltypes.MakeTrusted(querypb.Type_GEOMETRY, data[pos:pos+l]), l + int(metadata), nil default: - return sqltypes.NULL, 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "unsupported type %v", typ) + return sqltypes.NULL, 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unsupported type %v", typ) } } diff --git a/go/mysql/binlog/rbr_test.go b/go/mysql/binlog/rbr_test.go index 1dfaf90a33e..ce49e587e6c 100644 --- a/go/mysql/binlog/rbr_test.go +++ b/go/mysql/binlog/rbr_test.go @@ -550,7 +550,7 @@ func TestCellLengthAndData(t *testing.T) { } // Test CellValue. - out, l, err := CellValue(padded, 1, tcase.typ, tcase.metadata, &querypb.Field{Type: tcase.styp}) + out, l, err := CellValue(padded, 1, tcase.typ, tcase.metadata, &querypb.Field{Type: tcase.styp}, false) if err != nil || l != len(tcase.data) || out.Type() != tcase.out.Type() || !bytes.Equal(out.Raw(), tcase.out.Raw()) { t.Errorf("testcase cellData(%v,%v) returned unexpected result: %v %v %v, was expecting %v %v \nwant: %s\ngot: %s", tcase.typ, tcase.data, out, l, err, tcase.out, len(tcase.data), tcase.out.Raw(), out.Raw()) diff --git a/go/mysql/binlog_dump.go b/go/mysql/binlog_dump.go index d6768056974..cfacf742856 100644 --- a/go/mysql/binlog_dump.go +++ b/go/mysql/binlog_dump.go @@ -72,20 +72,20 @@ func (c *Conn) parseComBinlogDumpGTID(data []byte) (logFile string, logPos uint6 return logFile, logPos, position, readPacketErr } - if flags2&BinlogDumpNonBlock != 0 { - return logFile, logPos, position, io.EOF + dataSize, pos, ok := readUint32(data, pos) + if !ok { + return logFile, logPos, position, readPacketErr } - if flags2&BinlogThroughGTID != 0 { - dataSize, pos, ok := readUint32(data, pos) - if !ok { - return logFile, logPos, position, readPacketErr - } - if gtid := string(data[pos : pos+int(dataSize)]); gtid != "" { - position, err = replication.DecodePosition(gtid) - if err != nil { - return logFile, logPos, position, err - } + if gtidBytes := data[pos : pos+int(dataSize)]; len(gtidBytes) != 0 { + gtid, err := replication.NewMysql56GTIDSetFromSIDBlock(gtidBytes) + if err != nil { + return logFile, logPos, position, vterrors.Wrapf(err, "error parsing GTID from BinlogDumpGTID packet") } + // ComBinlogDumpGTID is a MySQL specific protocol. The GTID flavor is necessarily MySQL 56 + position = replication.Position{GTIDSet: gtid} + } + if flags2&BinlogDumpNonBlock != 0 { + return logFile, logPos, position, io.EOF } return logFile, logPos, position, nil diff --git a/go/mysql/binlog_event.go b/go/mysql/binlog_event.go index 5d472230d0e..90c2d7b9668 100644 --- a/go/mysql/binlog_event.go +++ b/go/mysql/binlog_event.go @@ -48,7 +48,7 @@ type BinlogEvent interface { IsValid() bool // General protocol events. - NextPosition() uint32 + NextPosition() uint64 // IsFormatDescription returns true if this is a // FORMAT_DESCRIPTION_EVENT. Do not call StripChecksum before @@ -86,9 +86,20 @@ type BinlogEvent interface { IsWriteRows() bool // IsUpdateRows returns true if this is a UPDATE_ROWS_EVENT. IsUpdateRows() bool + // IsPartialUpdateRows returs true if a partial JSON update event + // is found. These events are only seen in MySQL 8.0 if the mysqld + // instance has binlog_row_value_options=PARTIAL_JSON set. + IsPartialUpdateRows() bool // IsDeleteRows returns true if this is a DELETE_ROWS_EVENT. IsDeleteRows() bool + // IsPseudo is for custom implementations of GTID. + IsPseudo() bool + + // IsTransactionPayload returns true if a compressed transaction + // payload event is found (binlog_transaction_compression=ON). + IsTransactionPayload() bool + // Timestamp returns the timestamp from the event header. Timestamp() uint32 // ServerID returns the server ID from the event header. @@ -123,8 +134,8 @@ type BinlogEvent interface { TableMap(BinlogFormat) (*TableMap, error) // Rows returns a Rows struct representing data from a // {WRITE,UPDATE,DELETE}_ROWS_EVENT. This is only valid if - // IsWriteRows(), IsUpdateRows(), or IsDeleteRows() returns - // true. + // IsWriteRows(), IsUpdateRows(), IsPartialUpdateRows(), or + // IsDeleteRows() returns true. Rows(BinlogFormat, *TableMap) (Rows, error) // TransactionPayload returns a TransactionPayload type which provides // a GetNextEvent() method to iterate over the events contained within @@ -141,13 +152,6 @@ type BinlogEvent interface { // the same event and a nil checksum. StripChecksum(BinlogFormat) (ev BinlogEvent, checksum []byte, err error) - // IsPseudo is for custom implementations of GTID. - IsPseudo() bool - - // IsTransactionPayload returns true if a compressed transaction - // payload event is found (binlog_transaction_compression=ON). - IsTransactionPayload() bool - // Bytes returns the binary representation of the event Bytes() []byte } @@ -266,6 +270,12 @@ type Row struct { // It is only set for UPDATE and DELETE events. Identify []byte + // If this row was from a PartialUpdateRows event and it contains + // 1 or more JSON columns with partial values, then this will be + // set as a bitmap of which JSON columns in the AFTER image have + // partial values. + JSONPartialValues Bitmap + // Data is the raw data. // It is only set for WRITE and UPDATE events. Data []byte diff --git a/go/mysql/binlog_event_common.go b/go/mysql/binlog_event_common.go index c95873614f0..0bd9d401eaa 100644 --- a/go/mysql/binlog_event_common.go +++ b/go/mysql/binlog_event_common.go @@ -47,7 +47,7 @@ import ( // +----------------------------+ // | extra_headers 19 : x-19 | // +============================+ -// http://dev.mysql.com/doc/internals/en/event-header-fields.html +// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_replication_binlog_event.html#sect_protocol_replication_binlog_event_header type binlogEvent []byte const ( @@ -119,8 +119,9 @@ func (ev binlogEvent) Length() uint32 { } // NextPosition returns the nextPosition field from the header -func (ev binlogEvent) NextPosition() uint32 { - return binary.LittleEndian.Uint32(ev.Bytes()[13 : 13+4]) +func (ev binlogEvent) NextPosition() uint64 { + // Only 4 bytes are used for the next_position field in the header. + return uint64(binary.LittleEndian.Uint32(ev.Bytes()[13:17])) } // IsFormatDescription implements BinlogEvent.IsFormatDescription(). @@ -187,6 +188,11 @@ func (ev binlogEvent) IsUpdateRows() bool { ev.Type() == eUpdateRowsEventV2 } +// IsPartialUpdateRows implements BinlogEvent.IsPartialUpdateRows(). +func (ev binlogEvent) IsPartialUpdateRows() bool { + return ev.Type() == ePartialUpdateRowsEvent +} + // IsDeleteRows implements BinlogEvent.IsDeleteRows(). // We do not support v0. func (ev binlogEvent) IsDeleteRows() bool { diff --git a/go/mysql/binlog_event_filepos.go b/go/mysql/binlog_event_filepos.go index c71c8346964..8c60956faf1 100644 --- a/go/mysql/binlog_event_filepos.go +++ b/go/mysql/binlog_event_filepos.go @@ -75,12 +75,13 @@ func (ev *filePosBinlogEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte // nextPosition returns the next file position of the binlog. // If no information is available, it returns 0. -func (ev *filePosBinlogEvent) nextPosition(f BinlogFormat) uint32 { +func (ev *filePosBinlogEvent) nextPosition(f BinlogFormat) uint64 { if f.HeaderLength <= 13 { // Dead code. This is just a failsafe. return 0 } - return binary.LittleEndian.Uint32(ev.Bytes()[13:17]) + // The header only uses 4 bytes for the next_position. + return uint64(binary.LittleEndian.Uint32(ev.Bytes()[13:17])) } // rotate implements BinlogEvent.Rotate(). @@ -139,7 +140,7 @@ type filePosFakeEvent struct { timestamp uint32 } -func (ev filePosFakeEvent) NextPosition() uint32 { +func (ev filePosFakeEvent) NextPosition() uint64 { return 0 } @@ -203,6 +204,10 @@ func (ev filePosFakeEvent) IsUpdateRows() bool { return false } +func (ev filePosFakeEvent) IsPartialUpdateRows() bool { + return false +} + func (ev filePosFakeEvent) IsDeleteRows() bool { return false } @@ -279,7 +284,7 @@ type filePosGTIDEvent struct { gtid replication.FilePosGTID } -func newFilePosGTIDEvent(file string, pos uint32, timestamp uint32) filePosGTIDEvent { +func newFilePosGTIDEvent(file string, pos uint64, timestamp uint32) filePosGTIDEvent { return filePosGTIDEvent{ filePosFakeEvent: filePosFakeEvent{ timestamp: timestamp, diff --git a/go/mysql/binlog_event_mysql56_test.go b/go/mysql/binlog_event_mysql56_test.go index 5844779de63..ede2abece99 100644 --- a/go/mysql/binlog_event_mysql56_test.go +++ b/go/mysql/binlog_event_mysql56_test.go @@ -27,6 +27,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/mysql/replication" ) @@ -248,3 +249,480 @@ func TestMysql56SemiSyncAck(t *testing.T) { assert.True(t, e.IsQuery()) } } + +func TestMySQL56PartialUpdateRowsEvent(t *testing.T) { + format := BinlogFormat{ + HeaderSizes: []byte{ + 0, 13, 0, 8, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 98, 0, 4, 26, 8, 0, 0, 0, 8, 8, 8, 2, 0, 0, 0, 10, 10, 10, 42, 42, 0, 18, 52, 0, 10, 40, 0, + }, + ServerVersion: "8.0.40", + FormatVersion: 4, + HeaderLength: 19, + ChecksumAlgorithm: 1, + } + // This is from the following table structure: + // CREATE TABLE `customer` ( + // `customer_id` bigint NOT NULL AUTO_INCREMENT, + // `email` varbinary(128) DEFAULT NULL, + // `jd` json DEFAULT NULL, + // PRIMARY KEY (`customer_id`) + // ) + tm := &TableMap{ + Flags: 1, + Database: "vt_commerce", + Name: "customer", + Types: []byte{8, 15, 245}, + CanBeNull: Bitmap{ + data: []byte{6}, + count: 3, + }, + Metadata: []uint16{0, 128, 4}, + ColumnCollationIDs: []collations.ID{63}, + } + + testCases := []struct { + name string + rawEvent []byte + numRows int + want string + }{ + { + name: "INSERT", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='alice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"salary": 100}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='alice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_INSERT(@3, '$.role', 'manager') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='bob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"salary": 99}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='bob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_INSERT(@3, '$.role', 'manager') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=3 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='charlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"salary": 99}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=3 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='charlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_INSERT(@3, '$.role', 'manager') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"salary": 99}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_INSERT(@3, '$.role', 'manager') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=5 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='eve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"salary": 100}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=5 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='eve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_INSERT(@3, '$.role', 'manager') /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 196, 19, 87, 103, 39, 47, 142, 143, 12, 6, 2, 0, 0, 229, 104, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 16, 97, 108, 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, 0, 0, 0, 1, 0, 17, 0, 11, 0, 6, 0, 5, 100, 0, 115, + 97, 108, 97, 114, 121, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 97, 108, 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, + 0, 0, 1, 6, 36, 46, 114, 111, 108, 101, 9, 12, 7, 109, 97, 110, 97, 103, 101, 114, 0, 2, 0, 0, 0, 0, 0, 0, 0, 14, 98, 111, 98, 64, 100, 111, + 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, 0, 0, 0, 1, 0, 17, 0, 11, 0, 6, 0, 5, 99, 0, 115, 97, 108, 97, 114, 121, 1, 1, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 14, 98, 111, 98, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, 0, 0, 1, 6, 36, 46, 114, 111, 108, 101, 9, 12, 7, 109, 97, + 110, 97, 103, 101, 114, 0, 3, 0, 0, 0, 0, 0, 0, 0, 18, 99, 104, 97, 114, 108, 105, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, + 0, 0, 0, 0, 1, 0, 17, 0, 11, 0, 6, 0, 5, 99, 0, 115, 97, 108, 97, 114, 121, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 18, 99, 104, 97, 114, 108, 105, + 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, 0, 0, 1, 6, 36, 46, 114, 111, 108, 101, 9, 12, 7, 109, 97, 110, 97, 103, 101, + 114, 0, 4, 0, 0, 0, 0, 0, 0, 0, 14, 100, 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, 0, 0, 0, 1, 0, 17, 0, 11, 0, 6, 0, + 5, 99, 0, 115, 97, 108, 97, 114, 121, 1, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 14, 100, 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, + 0, 0, 0, 1, 6, 36, 46, 114, 111, 108, 101, 9, 12, 7, 109, 97, 110, 97, 103, 101, 114, 0, 5, 0, 0, 0, 0, 0, 0, 0, 14, 101, 118, 101, 64, 100, + 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, 0, 0, 0, 1, 0, 17, 0, 11, 0, 6, 0, 5, 100, 0, 115, 97, 108, 97, 114, 121, 1, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 14, 101, 118, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 18, 0, 0, 0, 1, 6, 36, 46, 114, 111, 108, 101, 9, 12, 7, 109, + 97, 110, 97, 103, 101, 114, + }, + numRows: 5, + want: "JSON_INSERT(%s, _utf8mb4'$.role', CAST(JSON_QUOTE(_utf8mb4'manager') as JSON))", + }, + { + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='alice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"role": "manager", "salary": 100}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='alice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REPLACE(@3, '$.role', 'IC') /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 155, 21, 87, 103, 39, 47, 142, 143, 12, 148, 0, 0, 0, 135, 106, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 16, 97, 108, 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 37, 0, 0, 0, 0, 2, 0, 36, 0, 18, 0, 4, 0, 22, 0, 6, 0, 12, 28, + 0, 5, 100, 0, 114, 111, 108, 101, 115, 97, 108, 97, 114, 121, 7, 109, 97, 110, 97, 103, 101, 114, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 97, 108, + 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 13, 0, 0, 0, 0, 6, 36, 46, 114, 111, 108, 101, 4, 12, 2, 73, 67, + }, + name: "REPLACE", + numRows: 1, + want: "JSON_REPLACE(%s, _utf8mb4'$.role', CAST(JSON_QUOTE(_utf8mb4'IC') as JSON))", + }, + { + name: "REMOVE", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='bob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"role": "manager", "salary": 99}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='bob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REMOVE(@3, '$.salary') /* JSON meta=4 nullable=1 is_null=0 */ + numRows: 1, + rawEvent: []byte{ + 176, 22, 87, 103, 39, 47, 142, 143, 12, 141, 0, 0, 0, 34, 108, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 14, 98, 111, 98, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 37, 0, 0, 0, 0, 2, 0, 36, 0, 18, 0, 4, 0, 22, 0, 6, 0, 12, 28, 0, 5, 99, 0, 114, + 111, 108, 101, 115, 97, 108, 97, 114, 121, 7, 109, 97, 110, 97, 103, 101, 114, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 14, 98, 111, 98, 64, 100, 111, 109, + 97, 105, 110, 46, 99, 111, 109, 10, 0, 0, 0, 2, 8, 36, 46, 115, 97, 108, 97, 114, 121, + }, + want: "JSON_REMOVE(%s, _utf8mb4'$.salary')", + }, + { + name: "REMOVE and REPLACE", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='alice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 100, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='alice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REMOVE( + // ### JSON_REPLACE(@3, '$.day', 'monday'), + // ### '$.favorite_color') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='bob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 99, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='bob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REMOVE( + // ### JSON_REPLACE(@3, '$.day', 'monday'), + // ### '$.favorite_color') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=3 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='charlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 99, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=3 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='charlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REMOVE( + // ### JSON_REPLACE(@3, '$.day', 'monday'), + // ### '$.favorite_color') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 99, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REMOVE( + // ### JSON_REPLACE(@3, '$.day', 'monday'), + // ### '$.favorite_color') /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=5 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='eve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 100, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=5 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='eve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REMOVE( + // ### JSON_REPLACE(@3, '$.day', 'monday'), + // ### '$.favorite_color') /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 227, 240, 86, 103, 39, 74, 58, 208, 33, 225, 3, 0, 0, 173, 122, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 16, 97, 108, 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, + 0, 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 100, 0, 12, 90, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, + 108, 111, 114, 115, 97, 108, 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 102, 114, 105, 100, 97, 121, + 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 97, 108, 105, 99, 101, + 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 34, 0, 0, 0, 0, 5, 36, 46, 100, 97, 121, 8, 12, 6, 109, 111, 110, 100, 97, 121, 2, 16, 36, + 46, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 0, 2, 0, 0, 0, 0, 0, 0, 0, 14, 98, 111, 98, 64, 100, 111, 109, 97, + 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, + 0, 12, 86, 0, 5, 99, 0, 12, 90, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, 97, 114, 121, 102, 97, 118, 111, + 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 5, 98, + 108, 97, 99, 107, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 14, 98, 111, 98, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 34, 0, 0, 0, 0, 5, 36, + 46, 100, 97, 121, 8, 12, 6, 109, 111, 110, 100, 97, 121, 2, 16, 36, 46, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 18, 99, 104, 97, 114, 108, 105, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, + 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 99, 0, 12, 90, 0, 100, 97, 121, 114, + 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 102, + 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 18, + 99, 104, 97, 114, 108, 105, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 34, 0, 0, 0, 0, 5, 36, 46, 100, 97, 121, 8, 12, 6, 109, + 111, 110, 100, 97, 121, 2, 16, 36, 46, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 0, 4, 0, 0, 0, 0, 0, 0, 0, 14, 100, + 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, 0, 6, 0, + 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 99, 0, 12, 90, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, + 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, + 101, 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 1, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 14, 100, 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, + 99, 111, 109, 34, 0, 0, 0, 0, 5, 36, 46, 100, 97, 121, 8, 12, 6, 109, 111, 110, 100, 97, 121, 2, 16, 36, 46, 102, 97, 118, 111, 114, 105, 116, + 101, 95, 99, 111, 108, 111, 114, 0, 5, 0, 0, 0, 0, 0, 0, 0, 14, 101, 118, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, + 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 100, 0, 12, 90, 0, 100, + 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, + 114, 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 1, 1, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 14, 101, 118, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 34, 0, 0, 0, 0, 5, 36, 46, 100, 97, 121, 8, 12, 6, 109, 111, 110, + 100, 97, 121, 2, 16, 36, 46, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, + }, + numRows: 5, + want: "JSON_REMOVE(JSON_REPLACE(%s, _utf8mb4'$.day', CAST(JSON_QUOTE(_utf8mb4'monday') as JSON)), _utf8mb4'$.favorite_color')", + }, + { + name: "INSERT and REMOVE and REPLACE", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=3 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='charlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "monday", "role": "manager", "salary": 99, "favorite_color": "red"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=3 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='charlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_INSERT( + // ### JSON_REMOVE( + // ### JSON_REPLACE(@3, '$.day', 'tuesday'), + // ### '$.favorite_color'), + // ### '$.hobby', 'skiing') /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 48, 25, 87, 103, 39, 47, 142, 143, 12, 234, 0, 0, 0, 0, 117, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 18, 99, 104, 97, 114, 108, 105, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 79, 0, 0, 0, 0, 4, 0, 78, 0, 32, 0, 3, 0, 35, 0, 4, 0, + 39, 0, 6, 0, 45, 0, 14, 0, 12, 59, 0, 12, 66, 0, 5, 99, 0, 12, 74, 0, 100, 97, 121, 114, 111, 108, 101, 115, 97, 108, 97, 114, 121, 102, 97, + 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 109, 111, 110, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, + 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 18, 99, 104, 97, 114, 108, 105, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 53, 0, 0, 0, 0, 5, 36, + 46, 100, 97, 121, 9, 12, 7, 116, 117, 101, 115, 100, 97, 121, 2, 16, 36, 46, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, + 1, 7, 36, 46, 104, 111, 98, 98, 121, 8, 12, 6, 115, 107, 105, 105, 110, 103, + }, + numRows: 1, + want: "JSON_INSERT(JSON_REMOVE(JSON_REPLACE(%s, _utf8mb4'$.day', CAST(JSON_QUOTE(_utf8mb4'tuesday') as JSON)), _utf8mb4'$.favorite_color'), _utf8mb4'$.hobby', CAST(JSON_QUOTE(_utf8mb4'skiing') as JSON))", + }, + { + name: "REPLACE with null", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"role": "manager", "salary": 99}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REPLACE(@3, '$.salary', null) /* JSON meta=4 nullable=1 is_null=0 * + rawEvent: []byte{ + 148, 26, 87, 103, 39, 47, 142, 143, 12, 144, 0, 0, 0, 158, 118, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 14, 100, 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 37, 0, 0, 0, 0, 2, 0, 36, 0, 18, 0, 4, 0, 22, 0, 6, 0, 12, 28, 0, 5, 99, 0, + 114, 111, 108, 101, 115, 97, 108, 97, 114, 121, 7, 109, 97, 110, 97, 103, 101, 114, 1, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 14, 100, 97, 110, 64, 100, 111, + 109, 97, 105, 110, 46, 99, 111, 109, 13, 0, 0, 0, 0, 8, 36, 46, 115, 97, 108, 97, 114, 121, 2, 4, 0, + }, + numRows: 1, + want: "JSON_REPLACE(%s, _utf8mb4'$.salary', CAST(_utf8mb4'null' as JSON))", + }, + { + name: "REPLACE 2 paths", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"role": "manager", "salary": null}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='dan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_REPLACE(@3, '$.salary', 110, + // ### '$.role', 'IC') /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 32, 32, 87, 103, 39, 26, 45, 78, 117, 158, 0, 0, 0, 145, 106, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 4, 0, 0, 0, 0, 0, 0, 0, 14, + 100, 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 37, 0, 0, 0, 0, 2, 0, 36, 0, 18, 0, 4, 0, 22, 0, 6, 0, 12, 28, 0, 5, 99, 0, 114, 111, + 108, 101, 115, 97, 108, 97, 114, 121, 7, 109, 97, 110, 97, 103, 101, 114, 1, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 14, 100, 97, 110, 64, 100, 111, 109, 97, + 105, 110, 46, 99, 111, 109, 27, 0, 0, 0, 0, 8, 36, 46, 115, 97, 108, 97, 114, 121, 3, 5, 110, 0, 0, 6, 36, 46, 114, 111, 108, 101, 4, 12, 2, 73, 67, + }, + numRows: 1, + want: "JSON_REPLACE(JSON_REPLACE(%s, _utf8mb4'$.salary', CAST(110 as JSON)), _utf8mb4'$.role', CAST(JSON_QUOTE(_utf8mb4'IC') as JSON))", + }, + { + name: "JSON null", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=5 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='neweve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 100, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=5 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='neweve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='null' /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 109, 200, 88, 103, 39, 57, 91, 186, 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 7, 7, 0, 5, 0, 0, 0, 0, 0, 0, 0, 17, 110, + 101, 119, 101, 118, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, + 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 100, 0, 12, 90, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, + 108, 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, + 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 17, 110, 101, 119, 101, 118, 101, 64, 100, 111, 109, 97, 105, 110, 46, + 99, 111, 109, 2, 0, 0, 0, 4, 0, + }, + numRows: 1, + want: "null", + }, + { + name: "null literal string", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=10 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='mlord@planetscale.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=NULL /* JSON meta=4 nullable=1 is_null=1 */ + // ### SET + // ### @1=10 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='mlord@planetscale.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='null' /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 178, 168, 89, 103, 39, 37, 191, 137, 18, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 7, 7, 4, 10, 0, 0, 0, 0, 0, 0, 0, 21, + 109, 108, 111, 114, 100, 64, 112, 108, 97, 110, 101, 116, 115, 99, 97, 108, 101, 46, 99, 111, 109, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 21, 109, 108, 111, + 114, 100, 64, 112, 108, 97, 110, 101, 116, 115, 99, 97, 108, 101, 46, 99, 111, 109, 6, 0, 0, 0, 12, 4, 110, 117, 108, 108, + }, + numRows: 1, + want: "\"null\"", + }, + { + name: "JSON object", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newalice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "wednesday", "role": "manager", "color": "red", "salary": 100}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newalice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=JSON_INSERT(@3, '$.misc', '{"address":"1012 S Park", "town":"Hastings", "state":"MI"}') /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 208, 160, 89, 103, 39, 202, 59, 214, 68, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 7, 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 19, 110, + 101, 119, 97, 108, 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 73, 0, 0, 0, 0, 4, 0, 72, 0, 32, 0, 3, 0, 35, 0, 4, 0, 39, 0, 5, + 0, 44, 0, 6, 0, 12, 50, 0, 12, 60, 0, 12, 68, 0, 5, 100, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, 97, 114, 121, 9, + 119, 101, 100, 110, 101, 115, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 19, 110, 101, 119, + 97, 108, 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 69, 0, 0, 0, 1, 6, 36, 46, 109, 105, 115, 99, 60, 12, 58, 123, 34, 97, 100, + 100, 114, 101, 115, 115, 34, 58, 34, 49, 48, 49, 50, 32, 83, 32, 80, 97, 114, 107, 34, 44, 32, 34, 116, 111, 119, 110, 34, 58, 34, 72, 97, 115, 116, + 105, 110, 103, 115, 34, 44, 32, 34, 115, 116, 97, 116, 101, 34, 58, 34, 77, 73, 34, 125, + }, + numRows: 1, + want: "JSON_INSERT(%s, _utf8mb4'$.misc', CAST(JSON_QUOTE(_utf8mb4'{\"address\":\"1012 S Park\", \"town\":\"Hastings\", \"state\":\"MI\"}') as JSON))", + }, + { + name: "JSON field not updated", + // The mysqlbinlog -vvv --base64-output=decode-rows output for the following event: + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newalice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 100, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=101 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newalice@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=@3 /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newbob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 99, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=102 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newbob@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=@3 /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=3 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newcharlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "monday", "role": "manager", "color": "red", "hobby": "skiing", "salary": 99}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=103 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newcharlie@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=@3 /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=4 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newdan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 99, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=104 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='newdan@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=@3 /* JSON meta=4 nullable=1 is_null=0 */ + // ### UPDATE `vt_commerce`.`customer` + // ### WHERE + // ### @1=5 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='neweve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3='{"day": "friday", "role": "manager", "color": "red", "salary": 100, "favorite_color": "black"}' /* JSON meta=4 nullable=1 is_null=0 */ + // ### SET + // ### @1=105 /* LONGINT meta=0 nullable=0 is_null=0 */ + // ### @2='neweve@domain.com' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */ + // ### @3=@3 /* JSON meta=4 nullable=1 is_null=0 */ + rawEvent: []byte{ + 194, 74, 100, 103, 39, 46, 144, 133, 54, 77, 3, 0, 0, 77, 128, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 255, 255, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 19, 110, 101, 119, 97, 108, 105, 99, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, + 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 100, 0, 12, 90, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, + 114, 115, 97, 108, 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, + 110, 97, 103, 101, 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 1, 1, 0, 101, 0, 0, 0, 0, 0, 0, 0, 19, 110, 101, 119, 97, 108, 105, 99, 101, 64, + 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 17, 110, 101, 119, 98, 111, 98, 64, 100, 111, 109, 97, 105, + 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, + 0, 5, 99, 0, 12, 90, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, + 95, 99, 111, 108, 111, 114, 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 1, 1, 0, + 102, 0, 0, 0, 0, 0, 0, 0, 17, 110, 101, 119, 98, 111, 98, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 21, 110, 101, 119, 99, 104, 97, 114, 108, 105, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 89, 0, 0, 0, 0, 5, 0, 88, 0, 39, 0, 3, 0, 42, + 0, 4, 0, 46, 0, 5, 0, 51, 0, 5, 0, 56, 0, 6, 0, 12, 62, 0, 12, 69, 0, 12, 77, 0, 12, 81, 0, 5, 99, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, + 111, 114, 104, 111, 98, 98, 121, 115, 97, 108, 97, 114, 121, 6, 109, 111, 110, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 6, + 115, 107, 105, 105, 110, 103, 1, 1, 0, 103, 0, 0, 0, 0, 0, 0, 0, 21, 110, 101, 119, 99, 104, 97, 114, 108, 105, 101, 64, 100, 111, 109, 97, 105, 110, + 46, 99, 111, 109, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 17, 110, 101, 119, 100, 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, + 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 99, 0, 12, 90, 0, 100, + 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, 97, 114, 121, 102, 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, + 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, 5, 98, 108, 97, 99, 107, 1, 1, 0, 104, 0, 0, 0, 0, 0, 0, 0, 17, + 110, 101, 119, 100, 97, 110, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 17, 110, 101, 119, 101, 118, + 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 97, 0, 0, 0, 0, 5, 0, 96, 0, 39, 0, 3, 0, 42, 0, 4, 0, 46, 0, 5, 0, 51, 0, 6, 0, 57, 0, 14, + 0, 12, 71, 0, 12, 78, 0, 12, 86, 0, 5, 100, 0, 12, 90, 0, 100, 97, 121, 114, 111, 108, 101, 99, 111, 108, 111, 114, 115, 97, 108, 97, 114, 121, 102, + 97, 118, 111, 114, 105, 116, 101, 95, 99, 111, 108, 111, 114, 6, 102, 114, 105, 100, 97, 121, 7, 109, 97, 110, 97, 103, 101, 114, 3, 114, 101, 100, + 5, 98, 108, 97, 99, 107, 1, 1, 0, 105, 0, 0, 0, 0, 0, 0, 0, 17, 110, 101, 119, 101, 118, 101, 64, 100, 111, 109, 97, 105, 110, 46, 99, 111, 109, 0, + 0, 0, 0, + }, + numRows: 5, + want: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + mysql56PartialUpdateRowEvent := NewMysql56BinlogEvent(tc.rawEvent) + require.True(t, mysql56PartialUpdateRowEvent.IsPartialUpdateRows()) + + ev, err := mysql56PartialUpdateRowEvent.Rows(format, tm) + require.NoError(t, err) + + assert.Equal(t, tc.numRows, len(ev.Rows)) + require.NoError(t, err) + + for i := range ev.Rows { + vals, err := ev.StringValuesForTests(tm, i) + require.NoError(t, err) + // The third column is the JSON column. + require.Equal(t, tc.want, vals[2]) + t.Logf("Rows: %v", vals) + } + }) + } +} diff --git a/go/mysql/binlog_event_rbr.go b/go/mysql/binlog_event_rbr.go index d77b7bcb9a0..29e0211bc36 100644 --- a/go/mysql/binlog_event_rbr.go +++ b/go/mysql/binlog_event_rbr.go @@ -283,10 +283,10 @@ func readColumnCollationIDs(data []byte, pos, count int) ([]collations.ID, error func (ev binlogEvent) Rows(f BinlogFormat, tm *TableMap) (Rows, error) { typ := ev.Type() data := ev.Bytes()[f.HeaderLength:] - hasIdentify := typ == eUpdateRowsEventV1 || typ == eUpdateRowsEventV2 || + hasIdentify := typ == eUpdateRowsEventV1 || typ == eUpdateRowsEventV2 || typ == ePartialUpdateRowsEvent || typ == eDeleteRowsEventV1 || typ == eDeleteRowsEventV2 hasData := typ == eWriteRowsEventV1 || typ == eWriteRowsEventV2 || - typ == eUpdateRowsEventV1 || typ == eUpdateRowsEventV2 + typ == eUpdateRowsEventV1 || typ == ePartialUpdateRowsEvent || typ == eUpdateRowsEventV2 result := Rows{} pos := 6 @@ -297,7 +297,7 @@ func (ev binlogEvent) Rows(f BinlogFormat, tm *TableMap) (Rows, error) { pos += 2 // version=2 have extra data here. - if typ == eWriteRowsEventV2 || typ == eUpdateRowsEventV2 || typ == eDeleteRowsEventV2 { + if typ == eWriteRowsEventV2 || typ == eUpdateRowsEventV2 || typ == ePartialUpdateRowsEvent || typ == eDeleteRowsEventV2 { // This extraDataLength contains the 2 bytes length. extraDataLength := binary.LittleEndian.Uint16(data[pos : pos+2]) pos += int(extraDataLength) @@ -311,6 +311,7 @@ func (ev binlogEvent) Rows(f BinlogFormat, tm *TableMap) (Rows, error) { numIdentifyColumns := 0 numDataColumns := 0 + numJSONColumns := 0 if hasIdentify { // Bitmap of the columns used for identify. @@ -324,6 +325,15 @@ func (ev binlogEvent) Rows(f BinlogFormat, tm *TableMap) (Rows, error) { numDataColumns = result.DataColumns.BitCount() } + // For PartialUpdateRowsEvents, we need to know how many JSON columns there are. + if ev.Type() == ePartialUpdateRowsEvent { + for c := 0; c < int(columnCount); c++ { + if tm.Types[c] == binlog.TypeJSON { + numJSONColumns++ + } + } + } + // One row at a time. for pos < len(data) { row := Row{} @@ -358,6 +368,17 @@ func (ev binlogEvent) Rows(f BinlogFormat, tm *TableMap) (Rows, error) { row.Identify = data[startPos:pos] } + if ev.Type() == ePartialUpdateRowsEvent { + // The first byte indicates whether or not any JSON values are partial. + // If it's not 1 then there's nothing special to do for the row as any + // columns use the full value. + partialJSON := uint8(data[pos]) + pos++ + if partialJSON == 1 { + row.JSONPartialValues, pos = newBitmap(data, pos, numJSONColumns) + } + } + if hasData { // Bitmap of columns that are null (amongst the ones that are present). row.NullColumns, pos = newBitmap(data, pos, numDataColumns) @@ -402,6 +423,7 @@ func (rs *Rows) StringValuesForTests(tm *TableMap, rowIndex int) ([]string, erro var result []string valueIndex := 0 + jsonIndex := 0 data := rs.Rows[rowIndex].Data pos := 0 for c := 0; c < rs.DataColumns.Count(); c++ { @@ -413,15 +435,24 @@ func (rs *Rows) StringValuesForTests(tm *TableMap, rowIndex int) ([]string, erro // This column is represented, but its value is NULL. result = append(result, "NULL") valueIndex++ + if tm.Types[c] == binlog.TypeJSON { + jsonIndex++ + } continue } - // We have real data - value, l, err := binlog.CellValue(data, pos, tm.Types[c], tm.Metadata[c], &querypb.Field{Type: querypb.Type_UINT64}) + partialJSON := false + if rs.Rows[rowIndex].JSONPartialValues.Count() > 0 && tm.Types[c] == binlog.TypeJSON { + partialJSON = rs.Rows[rowIndex].JSONPartialValues.Bit(jsonIndex) + jsonIndex++ + } + + // We have real data. + value, l, err := binlog.CellValue(data, pos, tm.Types[c], tm.Metadata[c], &querypb.Field{Type: querypb.Type_UINT64}, partialJSON) if err != nil { return nil, err } - result = append(result, value.ToString()) + result = append(result, value.RawStr()) pos += l valueIndex++ } @@ -452,7 +483,7 @@ func (rs *Rows) StringIdentifiesForTests(tm *TableMap, rowIndex int) ([]string, } // We have real data - value, l, err := binlog.CellValue(data, pos, tm.Types[c], tm.Metadata[c], &querypb.Field{Type: querypb.Type_UINT64}) + value, l, err := binlog.CellValue(data, pos, tm.Types[c], tm.Metadata[c], &querypb.Field{Type: querypb.Type_UINT64}, false) if err != nil { return nil, err } diff --git a/go/mysql/capabilities/capability.go b/go/mysql/capabilities/capability.go index 4015059e686..eac25585089 100644 --- a/go/mysql/capabilities/capability.go +++ b/go/mysql/capabilities/capability.go @@ -31,25 +31,26 @@ var ( type FlavorCapability int const ( - NoneFlavorCapability FlavorCapability = iota // default placeholder - FastDropTableFlavorCapability // supported in MySQL 8.0.23 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-23.html - TransactionalGtidExecutedFlavorCapability // - InstantDDLFlavorCapability // ALGORITHM=INSTANT general support - InstantAddLastColumnFlavorCapability // - InstantAddDropVirtualColumnFlavorCapability // - InstantAddDropColumnFlavorCapability // Adding/dropping column in any position/ordinal. - InstantChangeColumnDefaultFlavorCapability // - InstantExpandEnumCapability // - InstantChangeColumnVisibilityCapability // - MySQLUpgradeInServerFlavorCapability // - DynamicRedoLogCapacityFlavorCapability // supported in MySQL 8.0.30 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-30.html - DisableRedoLogFlavorCapability // supported in MySQL 8.0.21 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-21.html - CheckConstraintsCapability // supported in MySQL 8.0.16 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-16.html - PerformanceSchemaDataLocksTableCapability // supported in MySQL 8.0.1 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-1.html - InstantDDLXtrabackupCapability // Supported in 8.0.32 and above, solving a MySQL-vs-Xtrabackup bug starting 8.0.29 - ReplicaTerminologyCapability // Supported in 8.0.26 and above, using SHOW REPLICA STATUS and all variations. - BinaryLogStatus // Supported in 8.2.0 and above, uses SHOW BINARY LOG STATUS - RestrictFKOnNonStandardKey // Supported in 8.4.0 and above, restricts usage of non-standard indexes for foreign keys. + NoneFlavorCapability FlavorCapability = iota // default placeholder + FastDropTableFlavorCapability // supported in MySQL 8.0.23 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-23.html + TransactionalGtidExecutedFlavorCapability // + InstantDDLFlavorCapability // ALGORITHM=INSTANT general support + InstantAddLastColumnFlavorCapability // + InstantAddDropVirtualColumnFlavorCapability // + InstantAddDropColumnFlavorCapability // Adding/dropping column in any position/ordinal. + InstantChangeColumnDefaultFlavorCapability // + InstantExpandEnumCapability // + InstantChangeColumnVisibilityCapability // + MySQLUpgradeInServerFlavorCapability // + DynamicRedoLogCapacityFlavorCapability // supported in MySQL 8.0.30 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-30.html + DisableRedoLogFlavorCapability // supported in MySQL 8.0.21 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-21.html + CheckConstraintsCapability // supported in MySQL 8.0.16 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-16.html + PerformanceSchemaDataLocksTableCapability // supported in MySQL 8.0.1 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-1.html + PerformanceSchemaMetadataLocksTableCapability // supported in MySQL 8.0.2 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-2.html + InstantDDLXtrabackupCapability // Supported in 8.0.32 and above, solving a MySQL-vs-Xtrabackup bug starting 8.0.29 + ReplicaTerminologyCapability // Supported in 8.0.26 and above, using SHOW REPLICA STATUS and all variations. + BinaryLogStatus // Supported in 8.2.0 and above, uses SHOW BINARY LOG STATUS + RestrictFKOnNonStandardKey // Supported in 8.4.0 and above, restricts usage of non-standard indexes for foreign keys. ) type CapableOf func(capability FlavorCapability) (bool, error) @@ -97,6 +98,8 @@ func MySQLVersionHasCapability(serverVersion string, capability FlavorCapability return atLeast(8, 0, 0) case PerformanceSchemaDataLocksTableCapability: return atLeast(8, 0, 1) + case PerformanceSchemaMetadataLocksTableCapability: + return atLeast(8, 0, 2) case MySQLUpgradeInServerFlavorCapability: return atLeast(8, 0, 16) case CheckConstraintsCapability: diff --git a/go/mysql/capabilities/capability_test.go b/go/mysql/capabilities/capability_test.go index aeb18bed22e..cf5e693840e 100644 --- a/go/mysql/capabilities/capability_test.go +++ b/go/mysql/capabilities/capability_test.go @@ -218,6 +218,25 @@ func TestMySQLVersionCapableOf(t *testing.T) { version: "8.0.20", capability: PerformanceSchemaDataLocksTableCapability, isCapable: true, + }, { + version: "5.7.38", + capability: PerformanceSchemaMetadataLocksTableCapability, + isCapable: false, + }, + { + version: "8.0", + capability: PerformanceSchemaMetadataLocksTableCapability, + isCapable: false, + }, + { + version: "8.0.1", + capability: PerformanceSchemaMetadataLocksTableCapability, + isCapable: false, + }, + { + version: "8.0.2", + capability: PerformanceSchemaMetadataLocksTableCapability, + isCapable: true, }, { version: "8.0.29", diff --git a/go/mysql/collations/colldata/cached_size.go b/go/mysql/collations/colldata/cached_size.go index b348baaaed8..190e1731651 100644 --- a/go/mysql/collations/colldata/cached_size.go +++ b/go/mysql/collations/colldata/cached_size.go @@ -19,6 +19,10 @@ package colldata import hack "vitess.io/vitess/go/hack" +type cachedObject interface { + CachedSize(alloc bool) int64 +} + func (cached *eightbitWildcard) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -59,6 +63,10 @@ func (cached *unicodeWildcard) CachedSize(alloc bool) int64 { if alloc { size += int64(48) } + // field charset vitess.io/vitess/go/mysql/collations/charset.Charset + if cc, ok := cached.charset.(cachedObject); ok { + size += cc.CachedSize(true) + } // field pattern []rune { size += hack.RuntimeAllocSize(int64(cap(cached.pattern)) * int64(4)) diff --git a/go/mysql/collations/integration/collations_test.go b/go/mysql/collations/integration/collations_test.go index 519f4560faf..c599eceaa2e 100644 --- a/go/mysql/collations/integration/collations_test.go +++ b/go/mysql/collations/integration/collations_test.go @@ -45,7 +45,7 @@ var collationEnv *collations.Environment func init() { // We require MySQL 8.0 collations for the comparisons in the tests - collationEnv = collations.NewEnvironment("8.0.30") + collationEnv = collations.NewEnvironment("8.0.40") } func getSQLQueries(t *testing.T, testfile string) []string { diff --git a/go/mysql/config/config.go b/go/mysql/config/config.go index 6070d0d6248..4f9a8b3a734 100644 --- a/go/mysql/config/config.go +++ b/go/mysql/config/config.go @@ -1,5 +1,5 @@ package config const DefaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" -const DefaultMySQLVersion = "8.0.30" +const DefaultMySQLVersion = "8.0.40" const LegacyMySQLVersion = "5.7.31" diff --git a/go/mysql/conn.go b/go/mysql/conn.go index d4f870e660f..7eedc094c1e 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -399,7 +399,7 @@ func (c *Conn) readHeaderFrom(r io.Reader) (int, error) { return 0, vterrors.Wrapf(err, "io.ReadFull(header size) failed") } - sequence := uint8(c.header[3]) + sequence := c.header[3] if sequence != c.sequence { return 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid sequence, expected %v got %v", c.sequence, sequence) } diff --git a/go/mysql/datetime/spec.go b/go/mysql/datetime/spec.go index ce19126ce55..fe6b1521e43 100644 --- a/go/mysql/datetime/spec.go +++ b/go/mysql/datetime/spec.go @@ -359,10 +359,7 @@ func (t2 fmtFullTime24) parse(t *timeparts, bytes string) (string, bool) { type fmtWeek0 struct{} func (fmtWeek0) format(dst []byte, t DateTime, prec uint8) []byte { - year, week := t.Date.SundayWeek() - if year < t.Date.Year() { - week = 0 - } + week := t.Date.Week(0) return appendInt(dst, week, 2) } @@ -374,10 +371,7 @@ func (u fmtWeek0) parse(t *timeparts, bytes string) (string, bool) { type fmtWeek1 struct{} func (fmtWeek1) format(dst []byte, t DateTime, prec uint8) []byte { - year, week := t.Date.ISOWeek() - if year < t.Date.Year() { - week = 0 - } + week := t.Date.Week(1) return appendInt(dst, week, 2) } @@ -389,7 +383,7 @@ func (u fmtWeek1) parse(t *timeparts, bytes string) (string, bool) { type fmtWeek2 struct{} func (fmtWeek2) format(dst []byte, t DateTime, prec uint8) []byte { - _, week := t.Date.SundayWeek() + week := t.Date.Week(2) return appendInt(dst, week, 2) } @@ -401,7 +395,7 @@ func (v fmtWeek2) parse(t *timeparts, bytes string) (string, bool) { type fmtWeek3 struct{} func (fmtWeek3) format(dst []byte, t DateTime, prec uint8) []byte { - _, week := t.Date.ISOWeek() + week := t.Date.Week(3) return appendInt(dst, week, 2) } diff --git a/go/mysql/decimal/cached_size.go b/go/mysql/decimal/cached_size.go index e7258579f55..87f6c201b80 100644 --- a/go/mysql/decimal/cached_size.go +++ b/go/mysql/decimal/cached_size.go @@ -29,6 +29,7 @@ func (cached *Decimal) CachedSize(alloc bool) int64 { } // field value *math/big.Int if cached.value != nil { + size += hack.RuntimeAllocSize(int64(cap(cached.value.Bits())) * 4) size += hack.RuntimeAllocSize(int64(32)) } return size diff --git a/go/mysql/endtoend/replication_test.go b/go/mysql/endtoend/replication_test.go index d3b9a6722ea..a04f75c6b43 100644 --- a/go/mysql/endtoend/replication_test.go +++ b/go/mysql/endtoend/replication_test.go @@ -1064,7 +1064,7 @@ func valuesForTests(t *testing.T, rs *mysql.Rows, tm *mysql.TableMap, rowIndex i } // We have real data - value, l, err := binlog.CellValue(data, pos, tm.Types[c], tm.Metadata[c], &querypb.Field{Type: querypb.Type_UINT64}) + value, l, err := binlog.CellValue(data, pos, tm.Types[c], tm.Metadata[c], &querypb.Field{Type: querypb.Type_UINT64}, false) if err != nil { return nil, err } diff --git a/go/mysql/flavor_filepos.go b/go/mysql/flavor_filepos.go index 03d745468be..43278c9a0c4 100644 --- a/go/mysql/flavor_filepos.go +++ b/go/mysql/flavor_filepos.go @@ -84,7 +84,7 @@ func (flv *filePosFlavor) gtidMode(c *Conn) (string, error) { // serverUUID is part of the Flavor interface. func (flv *filePosFlavor) serverUUID(c *Conn) (string, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.server_uuid", 1, false) if err != nil { return "", err diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index b109e5ca385..a5993ac9aa0 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -60,7 +60,7 @@ var _ flavor = (*mysqlFlavor82)(nil) // primaryGTIDSet is part of the Flavor interface. func (mysqlFlavor) primaryGTIDSet(c *Conn) (replication.GTIDSet, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.gtid_executed", 1, false) if err != nil { return nil, err @@ -73,7 +73,7 @@ func (mysqlFlavor) primaryGTIDSet(c *Conn) (replication.GTIDSet, error) { // purgedGTIDSet is part of the Flavor interface. func (mysqlFlavor) purgedGTIDSet(c *Conn) (replication.GTIDSet, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.gtid_purged", 1, false) if err != nil { return nil, err @@ -86,7 +86,7 @@ func (mysqlFlavor) purgedGTIDSet(c *Conn) (replication.GTIDSet, error) { // serverUUID is part of the Flavor interface. func (mysqlFlavor) serverUUID(c *Conn) (string, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.server_uuid", 1, false) if err != nil { return "", err @@ -218,8 +218,18 @@ func (mysqlFlavor) sendBinlogDumpCommand(c *Conn, serverID uint32, binlogFilenam } // Build the command. - sidBlock := gtidSet.SIDBlock() - return c.WriteComBinlogDumpGTID(serverID, binlogFilename, 4, 0, sidBlock) + var sidBlock []byte + if gtidSet != nil { + sidBlock = gtidSet.SIDBlock() + } + var flags2 uint16 + if binlogFilename != "" { + flags2 |= BinlogThroughPosition + } + if len(sidBlock) > 0 { + flags2 |= BinlogThroughGTID + } + return c.WriteComBinlogDumpGTID(serverID, binlogFilename, 4, flags2, sidBlock) } // setReplicationPositionCommands is part of the Flavor interface. diff --git a/go/mysql/flavor_test.go b/go/mysql/flavor_test.go index 3d584b8293b..219b9803933 100644 --- a/go/mysql/flavor_test.go +++ b/go/mysql/flavor_test.go @@ -102,6 +102,15 @@ func TestServerVersionCapableOf(t *testing.T) { version: "8.0.20", capability: capabilities.PerformanceSchemaDataLocksTableCapability, isCapable: true, + }, { + version: "5.7.38", + capability: capabilities.PerformanceSchemaMetadataLocksTableCapability, + isCapable: false, + }, + { + version: "8.0.20", + capability: capabilities.PerformanceSchemaMetadataLocksTableCapability, + isCapable: true, }, { // Some ridiculous version diff --git a/go/mysql/query.go b/go/mysql/query.go index 26582cecbd9..720a533a772 100644 --- a/go/mysql/query.go +++ b/go/mysql/query.go @@ -404,6 +404,7 @@ func (c *Conn) ReadQueryResult(maxrows int, wantfields bool) (*sqltypes.Result, return &sqltypes.Result{ RowsAffected: packetOk.affectedRows, InsertID: packetOk.lastInsertID, + InsertIDChanged: packetOk.lastInsertID > 0, SessionStateChanges: packetOk.sessionStateData, StatusFlags: packetOk.statusFlags, Info: packetOk.info, diff --git a/go/mysql/query_test.go b/go/mysql/query_test.go index 6892508ac0c..01cbd6a8f30 100644 --- a/go/mysql/query_test.go +++ b/go/mysql/query_test.go @@ -22,17 +22,13 @@ import ( "sync" "testing" - "google.golang.org/protobuf/proto" - - "vitess.io/vitess/go/mysql/sqlerror" - - "vitess.io/vitess/go/mysql/collations" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" ) @@ -393,8 +389,9 @@ func TestQueries(t *testing.T) { // Typical Insert result checkQuery(t, "insert", sConn, cConn, &sqltypes.Result{ - RowsAffected: 0x8010203040506070, - InsertID: 0x0102030405060708, + RowsAffected: 0x8010203040506070, + InsertID: 0x0102030405060708, + InsertIDChanged: true, }) // Typical Select with TYPE_AND_NAME. @@ -702,6 +699,7 @@ func checkQueryInternal(t *testing.T, query string, sConn, cConn *Conn, result * got = &sqltypes.Result{} got.RowsAffected = result.RowsAffected got.InsertID = result.InsertID + got.InsertIDChanged = result.InsertIDUpdated() got.Fields, err = cConn.Fields() if err != nil { fatalError = fmt.Sprintf("Fields(%v) failed: %v", query, err) diff --git a/go/mysql/replication.go b/go/mysql/replication.go index 84c65842c7e..3dd369cd6fc 100644 --- a/go/mysql/replication.go +++ b/go/mysql/replication.go @@ -18,6 +18,7 @@ package mysql import ( "fmt" + "math" "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/vt/proto/vtrpc" @@ -32,9 +33,14 @@ const ( // This file contains the methods related to replication. // WriteComBinlogDump writes a ComBinlogDump command. -// See http://dev.mysql.com/doc/internals/en/com-binlog-dump.html for syntax. // Returns a SQLError. -func (c *Conn) WriteComBinlogDump(serverID uint32, binlogFilename string, binlogPos uint32, flags uint16) error { +// See: https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_binlog_dump.html +func (c *Conn) WriteComBinlogDump(serverID uint32, binlogFilename string, binlogPos uint64, flags uint16) error { + // The binary log file position is a uint64, but the protocol command + // only uses 4 bytes for the file position. + if binlogPos > math.MaxUint32 { + return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "binlog position %d is too large, it must fit into 32 bits", binlogPos) + } c.sequence = 0 length := 1 + // ComBinlogDump 4 + // binlog-pos @@ -43,7 +49,7 @@ func (c *Conn) WriteComBinlogDump(serverID uint32, binlogFilename string, binlog len(binlogFilename) // binlog-filename data, pos := c.startEphemeralPacketWithHeader(length) pos = writeByte(data, pos, ComBinlogDump) - pos = writeUint32(data, pos, binlogPos) + pos = writeUint32(data, pos, uint32(binlogPos)) pos = writeUint16(data, pos, flags) pos = writeUint32(data, pos, serverID) _ = writeEOFString(data, pos, binlogFilename) @@ -75,7 +81,8 @@ func (c *Conn) AnalyzeSemiSyncAckRequest(buf []byte) (strippedBuf []byte, ackReq // WriteComBinlogDumpGTID writes a ComBinlogDumpGTID command. // Only works with MySQL 5.6+ (and not MariaDB). // See http://dev.mysql.com/doc/internals/en/com-binlog-dump-gtid.html for syntax. -func (c *Conn) WriteComBinlogDumpGTID(serverID uint32, binlogFilename string, binlogPos uint64, flags uint16, gtidSet []byte) error { +// sidBlock must be the result of a gtidSet.SIDBlock() function. +func (c *Conn) WriteComBinlogDumpGTID(serverID uint32, binlogFilename string, binlogPos uint64, flags uint16, sidBlock []byte) error { c.sequence = 0 length := 1 + // ComBinlogDumpGTID 2 + // flags @@ -84,7 +91,7 @@ func (c *Conn) WriteComBinlogDumpGTID(serverID uint32, binlogFilename string, bi len(binlogFilename) + // binlog-filename 8 + // binlog-pos 4 + // data-size - len(gtidSet) // data + len(sidBlock) // data data, pos := c.startEphemeralPacketWithHeader(length) pos = writeByte(data, pos, ComBinlogDumpGTID) // nolint pos = writeUint16(data, pos, flags) // nolint @@ -92,8 +99,8 @@ func (c *Conn) WriteComBinlogDumpGTID(serverID uint32, binlogFilename string, bi pos = writeUint32(data, pos, uint32(len(binlogFilename))) // nolint pos = writeEOFString(data, pos, binlogFilename) // nolint pos = writeUint64(data, pos, binlogPos) // nolint - pos = writeUint32(data, pos, uint32(len(gtidSet))) // nolint - pos += copy(data[pos:], gtidSet) // nolint + pos = writeUint32(data, pos, uint32(len(sidBlock))) // nolint + pos += copy(data[pos:], sidBlock) // nolint if err := c.writeEphemeralPacket(); err != nil { return sqlerror.NewSQLErrorf(sqlerror.CRServerGone, sqlerror.SSUnknownSQLState, "%v", err) } diff --git a/go/mysql/replication/filepos_gtid.go b/go/mysql/replication/filepos_gtid.go index 850fb421915..95c7efcd3b1 100644 --- a/go/mysql/replication/filepos_gtid.go +++ b/go/mysql/replication/filepos_gtid.go @@ -33,14 +33,14 @@ func parseFilePosGTID(s string) (GTID, error) { return nil, fmt.Errorf("invalid FilePos GTID (%v): expecting file:pos", s) } - pos, err := strconv.ParseUint(parts[1], 0, 32) + pos, err := strconv.ParseUint(parts[1], 0, 64) if err != nil { return nil, fmt.Errorf("invalid FilePos GTID (%v): expecting pos to be an integer", s) } return FilePosGTID{ File: parts[0], - Pos: uint32(pos), + Pos: pos, }, nil } @@ -56,7 +56,7 @@ func ParseFilePosGTIDSet(s string) (GTIDSet, error) { // FilePosGTID implements GTID. type FilePosGTID struct { File string - Pos uint32 + Pos uint64 } // String implements GTID.String(). diff --git a/go/mysql/replication/filepos_gtid_test.go b/go/mysql/replication/filepos_gtid_test.go index 174aed6ccf9..6cef4756af2 100644 --- a/go/mysql/replication/filepos_gtid_test.go +++ b/go/mysql/replication/filepos_gtid_test.go @@ -23,7 +23,7 @@ import ( func Test_filePosGTID_String(t *testing.T) { type fields struct { file string - pos uint32 + pos uint64 } tests := []struct { name string @@ -35,6 +35,11 @@ func Test_filePosGTID_String(t *testing.T) { fields{file: "mysql-bin.166031", pos: 192394}, "mysql-bin.166031:192394", }, + { + "handles large position correctly", + fields{file: "vt-1448040107-bin.003222", pos: 4663881395}, + "vt-1448040107-bin.003222:4663881395", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -52,7 +57,7 @@ func Test_filePosGTID_String(t *testing.T) { func Test_filePosGTID_ContainsGTID(t *testing.T) { type fields struct { file string - pos uint32 + pos uint64 } type args struct { other GTID diff --git a/go/mysql/replication/mysql56_gtid_set_test.go b/go/mysql/replication/mysql56_gtid_set_test.go index bc5d5a6d6ec..bf87a992d5d 100644 --- a/go/mysql/replication/mysql56_gtid_set_test.go +++ b/go/mysql/replication/mysql56_gtid_set_test.go @@ -854,3 +854,18 @@ func TestMysql56GTIDSet_RemoveUUID(t *testing.T) { }) } } + +func TestSIDs(t *testing.T) { + var set Mysql56GTIDSet // nil + sids := set.SIDs() + assert.NotNil(t, sids) + assert.Empty(t, sids) + + gtid := "8bc65cca-3fe4-11ed-bbfb-091034d48b3e:1:4-24" + gtidSet, err := ParseMysql56GTIDSet(gtid) + require.NoError(t, err) + sids = gtidSet.SIDs() + assert.NotNil(t, sids) + require.Len(t, sids, 1) + assert.Equal(t, "8bc65cca-3fe4-11ed-bbfb-091034d48b3e", sids[0].String()) +} diff --git a/go/mysql/replication_constants.go b/go/mysql/replication_constants.go index 6b6e34b2333..27d0bd331ce 100644 --- a/go/mysql/replication_constants.go +++ b/go/mysql/replication_constants.go @@ -110,6 +110,9 @@ const ( //eViewChangeEvent = 37 //eXAPrepareLogEvent = 38 + // PartialUpdateRowsEvent when binlog_row_value_options=PARTIAL_JSON. + ePartialUpdateRowsEvent = 39 + // Transaction_payload_event when binlog_transaction_compression=ON. eTransactionPayloadEvent = 40 diff --git a/go/mysql/replication_test.go b/go/mysql/replication_test.go index c9a54485497..3f423624b68 100644 --- a/go/mysql/replication_test.go +++ b/go/mysql/replication_test.go @@ -17,12 +17,14 @@ limitations under the License. package mysql import ( + "math" "reflect" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/test/utils" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -37,6 +39,10 @@ func TestComBinlogDump(t *testing.T) { cConn.Close() }() + // Try to write a ComBinlogDump packet with a position greater than 4 bytes. + err := cConn.WriteComBinlogDump(1, "moofarm", math.MaxInt64, 0x0d0e) + require.Error(t, err) + // Write ComBinlogDump packet, read it, compare. if err := cConn.WriteComBinlogDump(0x01020304, "moofarm", 0x05060708, 0x090a); err != nil { t.Fatalf("WriteComBinlogDump failed: %v", err) @@ -83,12 +89,50 @@ func TestComBinlogDumpGTID(t *testing.T) { cConn.Close() }() + t.Run("WriteComBinlogDumpGTIDEmptyGTID", func(t *testing.T) { + // Write ComBinlogDumpGTID packet, read it, compare. + var flags uint16 = 0x0d0e + err := cConn.WriteComBinlogDumpGTID(0x01020304, "moofarm", 0x05060708090a0b0c, flags, []byte{}) + assert.NoError(t, err) + data, err := sConn.ReadPacket() + require.NoError(t, err, "sConn.ReadPacket - ComBinlogDumpGTID failed: %v", err) + require.NotEmpty(t, data) + require.EqualValues(t, data[0], ComBinlogDumpGTID) + + expectedData := []byte{ + ComBinlogDumpGTID, + 0x0e, 0x0d, // flags + 0x04, 0x03, 0x02, 0x01, // server-id + 0x07, 0x00, 0x00, 0x00, // binlog-filename-len + 'm', 'o', 'o', 'f', 'a', 'r', 'm', // bilog-filename + 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, // binlog-pos + 0x00, 0x00, 0x00, 0x00, // data-size is zero, no GTID payload + } + assert.Equal(t, expectedData, data) + logFile, logPos, pos, err := sConn.parseComBinlogDumpGTID(data) + require.NoError(t, err, "parseComBinlogDumpGTID failed: %v", err) + assert.Equal(t, "moofarm", logFile) + assert.Equal(t, uint64(0x05060708090a0b0c), logPos) + assert.True(t, pos.IsZero()) + }) + + sConn.sequence = 0 + t.Run("WriteComBinlogDumpGTID", func(t *testing.T) { // Write ComBinlogDumpGTID packet, read it, compare. - err := cConn.WriteComBinlogDumpGTID(0x01020304, "moofarm", 0x05060708090a0b0c, 0x0d0e, []byte{0xfa, 0xfb}) + var flags uint16 = 0x0d0e + assert.Equal(t, flags, flags|BinlogThroughGTID) + gtidSet, err := replication.ParseMysql56GTIDSet("16b1039f-22b6-11ed-b765-0a43f95f28a3:1-243") + require.NoError(t, err) + sidBlock := gtidSet.SIDBlock() + assert.Len(t, sidBlock, 48) + + err = cConn.WriteComBinlogDumpGTID(0x01020304, "moofarm", 0x05060708090a0b0c, flags, sidBlock) assert.NoError(t, err) data, err := sConn.ReadPacket() require.NoError(t, err, "sConn.ReadPacket - ComBinlogDumpGTID failed: %v", err) + require.NotEmpty(t, data) + require.EqualValues(t, data[0], ComBinlogDumpGTID) expectedData := []byte{ ComBinlogDumpGTID, @@ -97,10 +141,15 @@ func TestComBinlogDumpGTID(t *testing.T) { 0x07, 0x00, 0x00, 0x00, // binlog-filename-len 'm', 'o', 'o', 'f', 'a', 'r', 'm', // bilog-filename 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, // binlog-pos - 0x02, 0x00, 0x00, 0x00, // data-size - 0xfa, 0xfb, // data + 0x30, 0x00, 0x00, 0x00, // data-size } + expectedData = append(expectedData, sidBlock...) // data assert.Equal(t, expectedData, data) + logFile, logPos, pos, err := sConn.parseComBinlogDumpGTID(data) + require.NoError(t, err, "parseComBinlogDumpGTID failed: %v", err) + assert.Equal(t, "moofarm", logFile) + assert.Equal(t, uint64(0x05060708090a0b0c), logPos) + assert.Equal(t, gtidSet, pos.GTIDSet) }) sConn.sequence = 0 diff --git a/go/pools/smartconnpool/pool.go b/go/pools/smartconnpool/pool.go index d49032f34a1..b024cc656df 100644 --- a/go/pools/smartconnpool/pool.go +++ b/go/pools/smartconnpool/pool.go @@ -92,6 +92,7 @@ type RefreshCheck func() (bool, error) type Config[C Connection] struct { Capacity int64 + MaxIdleCount int64 IdleTimeout time.Duration MaxLifetime time.Duration RefreshInterval time.Duration @@ -123,6 +124,8 @@ type ConnPool[C Connection] struct { active atomic.Int64 // capacity is the maximum number of connections that this pool can open capacity atomic.Int64 + // maxIdleCount is the maximum idle connections in the pool + idleCount atomic.Int64 // workers is a waitgroup for all the currently running worker goroutines workers sync.WaitGroup @@ -138,6 +141,8 @@ type ConnPool[C Connection] struct { // maxCapacity is the maximum value to which capacity can be set; when the pool // is re-opened, it defaults to this capacity maxCapacity int64 + // maxIdleCount is the maximum idle connections in the pool + maxIdleCount int64 // maxLifetime is the maximum time a connection can be open maxLifetime atomic.Int64 // idleTimeout is the maximum time a connection can remain idle @@ -158,6 +163,7 @@ func NewPool[C Connection](config *Config[C]) *ConnPool[C] { pool := &ConnPool[C]{} pool.freshSettingsStack.Store(-1) pool.config.maxCapacity = config.Capacity + pool.config.maxIdleCount = config.MaxIdleCount pool.config.maxLifetime.Store(config.MaxLifetime.Nanoseconds()) pool.config.idleTimeout.Store(config.IdleTimeout.Nanoseconds()) pool.config.refreshInterval.Store(config.RefreshInterval.Nanoseconds()) @@ -192,6 +198,7 @@ func (pool *ConnPool[C]) runWorker(close <-chan struct{}, interval time.Duration func (pool *ConnPool[C]) open() { pool.close = make(chan struct{}) pool.capacity.Store(pool.config.maxCapacity) + pool.setIdleCount() // The expire worker takes care of removing from the waiter list any clients whose // context has been cancelled. @@ -315,6 +322,16 @@ func (pool *ConnPool[C]) MaxCapacity() int64 { return pool.config.maxCapacity } +func (pool *ConnPool[C]) setIdleCount() { + capacity := pool.Capacity() + maxIdleCount := pool.config.maxIdleCount + if maxIdleCount == 0 || maxIdleCount > capacity { + pool.idleCount.Store(capacity) + } else { + pool.idleCount.Store(maxIdleCount) + } +} + // InUse returns the number of connections that the pool has lent out to clients and that // haven't been returned yet. func (pool *ConnPool[C]) InUse() int64 { @@ -340,6 +357,10 @@ func (pool *ConnPool[C]) SetIdleTimeout(duration time.Duration) { pool.config.idleTimeout.Store(duration.Nanoseconds()) } +func (pool *ConnPool[D]) IdleCount() int64 { + return pool.idleCount.Load() +} + func (pool *ConnPool[D]) RefreshInterval() time.Duration { return time.Duration(pool.config.refreshInterval.Load()) } @@ -396,6 +417,10 @@ func (pool *ConnPool[C]) put(conn *Pooled[C]) { } if !pool.wait.tryReturnConn(conn) { + if pool.closeOnIdleLimitReached(conn) { + return + } + connSetting := conn.Conn.Setting() if connSetting == nil { pool.clean.Push(conn) @@ -407,6 +432,23 @@ func (pool *ConnPool[C]) put(conn *Pooled[C]) { } } +// closeOnIdleLimitReached closes a connection if the number of idle connections (active - inuse) in the pool +// exceeds the idleCount limit. It returns true if the connection is closed, false otherwise. +func (pool *ConnPool[C]) closeOnIdleLimitReached(conn *Pooled[C]) bool { + for { + open := pool.active.Load() + idle := open - pool.borrowed.Load() + if idle <= pool.idleCount.Load() { + return false + } + if pool.active.CompareAndSwap(open, open-1) { + pool.Metrics.idleClosed.Add(1) + conn.Close() + return true + } + } +} + func (pool *ConnPool[D]) extendedMaxLifetime() time.Duration { maxLifetime := pool.config.maxLifetime.Load() if maxLifetime == 0 { @@ -629,6 +671,9 @@ func (pool *ConnPool[C]) setCapacity(ctx context.Context, newcap int64) error { if oldcap == newcap { return nil } + // update the idle count to match the new capacity if necessary + // wait for connections to be returned to the pool if we're reducing the capacity. + defer pool.setIdleCount() const delay = 10 * time.Millisecond @@ -732,6 +777,9 @@ func (pool *ConnPool[C]) RegisterStats(stats *servenv.Exporter, name string) { // the smartconnpool doesn't have a maximum capacity return pool.Capacity() }) + stats.NewGaugeFunc(name+"IdleAllowed", "Tablet server conn pool idle allowed limit", func() int64 { + return pool.IdleCount() + }) stats.NewCounterFunc(name+"WaitCount", "Tablet server conn pool wait count", func() int64 { return pool.Metrics.WaitCount() }) diff --git a/go/pools/smartconnpool/pool_test.go b/go/pools/smartconnpool/pool_test.go index 701327005ad..44bd431d189 100644 --- a/go/pools/smartconnpool/pool_test.go +++ b/go/pools/smartconnpool/pool_test.go @@ -746,6 +746,51 @@ func TestExtendedLifetimeTimeout(t *testing.T) { } } +// TestMaxIdleCount tests the MaxIdleCount setting, to check if the pool closes +// the idle connections when the number of idle connections exceeds the limit. +func TestMaxIdleCount(t *testing.T) { + testMaxIdleCount := func(t *testing.T, setting *Setting, maxIdleCount int64, expClosedConn int) { + var state TestState + + ctx := context.Background() + p := NewPool(&Config[*TestConn]{ + Capacity: 5, + MaxIdleCount: maxIdleCount, + LogWait: state.LogWait, + }).Open(newConnector(&state), nil) + + defer p.Close() + + var conns []*Pooled[*TestConn] + for i := 0; i < 5; i++ { + r, err := p.Get(ctx, setting) + require.NoError(t, err) + assert.EqualValues(t, i+1, state.open.Load()) + assert.EqualValues(t, 0, p.Metrics.IdleClosed()) + + conns = append(conns, r) + } + + for _, conn := range conns { + p.put(conn) + } + + closedConn := 0 + for _, conn := range conns { + if conn.Conn.IsClosed() { + closedConn++ + } + } + assert.EqualValues(t, expClosedConn, closedConn) + assert.EqualValues(t, expClosedConn, p.Metrics.IdleClosed()) + } + + t.Run("WithoutSettings", func(t *testing.T) { testMaxIdleCount(t, nil, 2, 3) }) + t.Run("WithSettings", func(t *testing.T) { testMaxIdleCount(t, sFoo, 2, 3) }) + t.Run("WithoutSettings-MaxIdleCount-Zero", func(t *testing.T) { testMaxIdleCount(t, nil, 0, 0) }) + t.Run("WithSettings-MaxIdleCount-Zero", func(t *testing.T) { testMaxIdleCount(t, sFoo, 0, 0) }) +} + func TestCreateFail(t *testing.T) { var state TestState state.chaos.failConnect = true diff --git a/go/sqltypes/cached_size.go b/go/sqltypes/cached_size.go index 632c8249455..53bc407278d 100644 --- a/go/sqltypes/cached_size.go +++ b/go/sqltypes/cached_size.go @@ -37,6 +37,14 @@ func (cached *Result) CachedSize(alloc bool) int64 { // field Rows []vitess.io/vitess/go/sqltypes.Row { size += hack.RuntimeAllocSize(int64(cap(cached.Rows)) * int64(24)) + for _, elem := range cached.Rows { + { + size += hack.RuntimeAllocSize(int64(cap(elem)) * int64(32)) + for _, elem := range elem { + size += elem.CachedSize(false) + } + } + } } // field SessionStateChanges string size += hack.RuntimeAllocSize(int64(len(cached.SessionStateChanges))) diff --git a/go/sqltypes/proto3.go b/go/sqltypes/proto3.go index 6eaefcf4b0c..0ca03b153cf 100644 --- a/go/sqltypes/proto3.go +++ b/go/sqltypes/proto3.go @@ -103,6 +103,7 @@ func ResultToProto3(qr *Result) *querypb.QueryResult { Fields: qr.Fields, RowsAffected: qr.RowsAffected, InsertId: qr.InsertID, + InsertIdChanged: qr.InsertIDChanged, Rows: RowsToProto3(qr.Rows), Info: qr.Info, SessionStateChanges: qr.SessionStateChanges, @@ -119,6 +120,7 @@ func Proto3ToResult(qr *querypb.QueryResult) *Result { Fields: qr.Fields, RowsAffected: qr.RowsAffected, InsertID: qr.InsertId, + InsertIDChanged: qr.InsertIdChanged, Rows: proto3ToRows(qr.Fields, qr.Rows), Info: qr.Info, SessionStateChanges: qr.SessionStateChanges, @@ -136,6 +138,7 @@ func CustomProto3ToResult(fields []*querypb.Field, qr *querypb.QueryResult) *Res Fields: qr.Fields, RowsAffected: qr.RowsAffected, InsertID: qr.InsertId, + InsertIDChanged: qr.InsertIdChanged, Rows: proto3ToRows(fields, qr.Rows), Info: qr.Info, SessionStateChanges: qr.SessionStateChanges, diff --git a/go/sqltypes/proto3_test.go b/go/sqltypes/proto3_test.go index 5e0bffd2a73..61674b2d1e4 100644 --- a/go/sqltypes/proto3_test.go +++ b/go/sqltypes/proto3_test.go @@ -39,9 +39,10 @@ func TestResult(t *testing.T) { Type: Float64, }} sqlResult := &Result{ - Fields: fields, - InsertID: 1, - RowsAffected: 2, + Fields: fields, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{{ TestValue(VarChar, "aa"), TestValue(Int64, "1"), @@ -53,9 +54,10 @@ func TestResult(t *testing.T) { }}, } p3Result := &querypb.QueryResult{ - Fields: fields, - InsertId: 1, - RowsAffected: 2, + Fields: fields, + InsertId: 1, + InsertIdChanged: true, + RowsAffected: 2, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("aa12"), @@ -105,18 +107,20 @@ func TestResults(t *testing.T) { Type: Float64, }} sqlResults := []Result{{ - Fields: fields1, - InsertID: 1, - RowsAffected: 2, + Fields: fields1, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{{ TestValue(VarChar, "aa"), TestValue(Int64, "1"), TestValue(Float64, "2"), }}, }, { - Fields: fields2, - InsertID: 3, - RowsAffected: 4, + Fields: fields2, + InsertID: 3, + InsertIDChanged: true, + RowsAffected: 4, Rows: [][]Value{{ TestValue(VarChar, "bb"), TestValue(Int64, "3"), @@ -124,17 +128,19 @@ func TestResults(t *testing.T) { }}, }} p3Results := []*querypb.QueryResult{{ - Fields: fields1, - InsertId: 1, - RowsAffected: 2, + Fields: fields1, + InsertId: 1, + InsertIdChanged: true, + RowsAffected: 2, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("aa12"), }}, }, { - Fields: fields2, - InsertId: 3, - RowsAffected: 4, + Fields: fields2, + InsertId: 3, + InsertIdChanged: true, + RowsAffected: 4, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("bb34"), @@ -176,9 +182,10 @@ func TestQueryReponses(t *testing.T) { queryResponses := []QueryResponse{ { QueryResult: &Result{ - Fields: fields1, - InsertID: 1, - RowsAffected: 2, + Fields: fields1, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{{ TestValue(VarChar, "aa"), TestValue(Int64, "1"), @@ -188,9 +195,10 @@ func TestQueryReponses(t *testing.T) { QueryError: nil, }, { QueryResult: &Result{ - Fields: fields2, - InsertID: 3, - RowsAffected: 4, + Fields: fields2, + InsertID: 3, + InsertIDChanged: true, + RowsAffected: 4, Rows: [][]Value{{ TestValue(VarChar, "bb"), TestValue(Int64, "3"), @@ -208,9 +216,10 @@ func TestQueryReponses(t *testing.T) { { Error: nil, Result: &querypb.QueryResult{ - Fields: fields1, - InsertId: 1, - RowsAffected: 2, + Fields: fields1, + InsertId: 1, + InsertIdChanged: true, + RowsAffected: 2, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("aa12"), @@ -219,9 +228,10 @@ func TestQueryReponses(t *testing.T) { }, { Error: nil, Result: &querypb.QueryResult{ - Fields: fields2, - InsertId: 3, - RowsAffected: 4, + Fields: fields2, + InsertId: 3, + InsertIdChanged: true, + RowsAffected: 4, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("bb34"), diff --git a/go/sqltypes/result.go b/go/sqltypes/result.go index 389b7fff620..b3cc0fd5573 100644 --- a/go/sqltypes/result.go +++ b/go/sqltypes/result.go @@ -31,6 +31,7 @@ type Result struct { Fields []*querypb.Field `json:"fields"` RowsAffected uint64 `json:"rows_affected"` InsertID uint64 `json:"insert_id"` + InsertIDChanged bool `json:"insert_id_changed"` Rows []Row `json:"rows"` SessionStateChanges string `json:"session_state_changes"` StatusFlags uint16 `json:"status_flags"` @@ -92,6 +93,7 @@ func (result *Result) Copy() *Result { out := &Result{ RowsAffected: result.RowsAffected, InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, SessionStateChanges: result.SessionStateChanges, StatusFlags: result.StatusFlags, Info: result.Info, @@ -116,6 +118,7 @@ func (result *Result) ShallowCopy() *Result { return &Result{ Fields: result.Fields, InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, RowsAffected: result.RowsAffected, Info: result.Info, SessionStateChanges: result.SessionStateChanges, @@ -129,6 +132,7 @@ func (result *Result) Metadata() *Result { return &Result{ Fields: result.Fields, InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, RowsAffected: result.RowsAffected, Info: result.Info, SessionStateChanges: result.SessionStateChanges, @@ -153,6 +157,7 @@ func (result *Result) Truncate(l int) *Result { out := &Result{ InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, RowsAffected: result.RowsAffected, Info: result.Info, SessionStateChanges: result.SessionStateChanges, @@ -198,6 +203,7 @@ func (result *Result) Equal(other *Result) bool { return FieldsEqual(result.Fields, other.Fields) && result.RowsAffected == other.RowsAffected && result.InsertID == other.InsertID && + result.InsertIDChanged == other.InsertIDChanged && slices.EqualFunc(result.Rows, other.Rows, func(a, b Row) bool { return RowEqual(a, b) }) @@ -324,15 +330,13 @@ func (result *Result) StripMetadata(incl querypb.ExecuteOptions_IncludedFields) // to another result.Note currently it doesn't handle cases like // if two results have different fields.We will enhance this function. func (result *Result) AppendResult(src *Result) { - if src.RowsAffected == 0 && len(src.Rows) == 0 && len(src.Fields) == 0 { - return - } - if result.Fields == nil { - result.Fields = src.Fields - } result.RowsAffected += src.RowsAffected - if src.InsertID != 0 { + if src.InsertIDUpdated() { result.InsertID = src.InsertID + result.InsertIDChanged = true + } + if len(result.Fields) == 0 { + result.Fields = src.Fields } result.Rows = append(result.Rows, src.Rows...) } @@ -351,3 +355,7 @@ func (result *Result) IsMoreResultsExists() bool { func (result *Result) IsInTransaction() bool { return result.StatusFlags&ServerStatusInTrans == ServerStatusInTrans } + +func (result *Result) InsertIDUpdated() bool { + return result.InsertIDChanged || result.InsertID > 0 +} diff --git a/go/sqltypes/result_test.go b/go/sqltypes/result_test.go index d8075ec0633..c358497baf3 100644 --- a/go/sqltypes/result_test.go +++ b/go/sqltypes/result_test.go @@ -21,11 +21,17 @@ import ( "github.com/stretchr/testify/assert" - "vitess.io/vitess/go/test/utils" - querypb "vitess.io/vitess/go/vt/proto/query" ) +func assertEqualResults(t *testing.T, a, b *Result) { + t.Helper() + assert.Truef(t, a.Equal(b), "Results are not equal: \n%v\n%v", a, b) + if !a.Equal(b) { + t.Errorf("Results are not equal: %v %v", a, b) + } +} + func TestRepair(t *testing.T) { fields := []*querypb.Field{{ Type: Int64, @@ -45,9 +51,7 @@ func TestRepair(t *testing.T) { }, } in.Repair(fields) - if !in.Equal(want) { - t.Errorf("Repair:\n%#v, want\n%#v", in, want) - } + assertEqualResults(t, in, want) } func TestCopy(t *testing.T) { @@ -57,8 +61,9 @@ func TestCopy(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 2, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, @@ -66,7 +71,7 @@ func TestCopy(t *testing.T) { }, } out := in.Copy() - utils.MustMatch(t, in, out) + assertEqualResults(t, in, out) } func TestTruncate(t *testing.T) { @@ -76,8 +81,9 @@ func TestTruncate(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 2, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, @@ -86,26 +92,23 @@ func TestTruncate(t *testing.T) { } out := in.Truncate(0) - if !out.Equal(in) { - t.Errorf("Truncate(0):\n%v, want\n%v", out, in) - } + assertEqualResults(t, in, out) out = in.Truncate(1) want := &Result{ Fields: []*querypb.Field{{ Type: Int64, }}, - InsertID: 1, - RowsAffected: 2, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "1")}, {TestValue(Int64, "2")}, {TestValue(Int64, "3")}, }, } - if !out.Equal(want) { - t.Errorf("Truncate(1):\n%v, want\n%v", out, want) - } + assertEqualResults(t, out, want) } func TestStripMetaData(t *testing.T) { @@ -283,9 +286,7 @@ func TestStripMetaData(t *testing.T) { t.Run(tcase.name, func(t *testing.T) { inCopy := tcase.in.Copy() out := inCopy.StripMetadata(tcase.includedFields) - if !out.Equal(tcase.expected) { - t.Errorf("StripMetaData unexpected result for %v: %v", tcase.name, out) - } + assertEqualResults(t, out, tcase.expected) if len(tcase.in.Fields) > 0 { // check the out array is different than the in array. if out.Fields[0] == inCopy.Fields[0] && tcase.includedFields != querypb.ExecuteOptions_ALL { @@ -293,7 +294,7 @@ func TestStripMetaData(t *testing.T) { } } // check we didn't change the original result. - utils.MustMatch(t, tcase.in, inCopy) + assertEqualResults(t, tcase.in, inCopy) }) } } @@ -305,8 +306,9 @@ func TestAppendResult(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 2, + InsertIDChanged: true, + InsertID: 1, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, {TestValue(Int64, "3"), TestValue(VarChar, "")}, @@ -319,8 +321,9 @@ func TestAppendResult(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 3, - RowsAffected: 4, + InsertID: 3, + InsertIDChanged: true, + RowsAffected: 4, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, }, @@ -332,8 +335,9 @@ func TestAppendResult(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 6, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 6, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, @@ -342,10 +346,7 @@ func TestAppendResult(t *testing.T) { } result.AppendResult(src) - - if !result.Equal(want) { - t.Errorf("Got:\n%#v, want:\n%#v", result, want) - } + assertEqualResults(t, result, want) } func TestReplaceKeyspace(t *testing.T) { diff --git a/go/sqltypes/value.go b/go/sqltypes/value.go index 7fb6fa80396..438b51a13ba 100644 --- a/go/sqltypes/value.go +++ b/go/sqltypes/value.go @@ -26,7 +26,6 @@ import ( "math/big" "strconv" "strings" - "time" "google.golang.org/protobuf/encoding/protowire" @@ -436,100 +435,6 @@ func (v Value) String() string { return fmt.Sprintf("%v(%s)", Type(v.typ), v.val) } -// ToTime returns the value as a time.Time in UTC. -// NULL values are returned as zero time. -func (v Value) ToTime() (time.Time, error) { - return v.ToTimeInLocation(time.UTC) -} - -// ToTimeInLocation returns the value as a time.Time in the provided location. -// NULL values are returned as zero time. -func (v Value) ToTimeInLocation(loc *time.Location) (time.Time, error) { - if v.Type() == Null { - return time.Time{}, nil - } - switch v.Type() { - case Datetime, Timestamp: - return datetimeToNative(v, loc) - case Date: - return dateToNative(v, loc) - default: - return time.Time{}, ErrIncompatibleTypeCast - } -} - -// ErrInvalidTime is returned when we fail to parse a datetime -// string from MySQL. This should never happen unless things are -// seriously messed up. -var ErrInvalidTime = errors.New("invalid MySQL time string") - -var isoTimeFormat = "2006-01-02 15:04:05.999999" -var isoNullTime = "0000-00-00 00:00:00.000000" -var isoTimeLength = len(isoTimeFormat) - -// parseISOTime pases a time string in MySQL's textual datetime format. -// This is very similar to ISO8601, with some differences: -// -// - There is no T separator between the date and time sections; -// a space is used instead. -// - There is never a timezone section in the string, as these datetimes -// are not timezone-aware. There isn't a Z value for UTC times for -// the same reason. -// -// Note that this function can handle both DATE (which should _always_ have -// a length of 10) and DATETIME strings (which have a variable length, 18+ -// depending on the number of decimal sub-second places). -// -// Also note that this function handles the case where MySQL returns a NULL -// time (with a string where all sections are zeroes) by returning a zeroed -// out time.Time object. NULL time strings are not considered a parsing error. -// -// See: isoTimeFormat -func parseISOTime(tstr string, loc *time.Location, minLen, maxLen int) (t time.Time, err error) { - tlen := len(tstr) - if tlen < minLen || tlen > maxLen { - err = ErrInvalidTime - return - } - - if tstr == isoNullTime[:tlen] { - // This is what MySQL would send when the date is NULL, - // so return an empty time.Time instead. - // This is not a parsing error - return - } - - if loc == nil { - loc = time.UTC - } - - // Since the time format returned from MySQL never has a Timezone - // section, ParseInLocation will initialize the time.Time struct - // with the default `loc` we're passing here. - return time.ParseInLocation(isoTimeFormat[:tlen], tstr, loc) -} - -// datetimeToNative converts a Datetime Value into a time.Time -func datetimeToNative(v Value, loc *time.Location) (time.Time, error) { - // Valid format string offsets for a DATETIME - // |DATETIME |19+ - // |------------------|------| - // "2006-01-02 15:04:05.999999" - return parseISOTime(v.ToString(), loc, 19, isoTimeLength) -} - -// dateToNative converts a Date Value into a time.Time. -// Note that there's no specific type in the Go stdlib to represent -// dates without time components, so the returned Time will have -// their hours/mins/seconds zeroed out. -func dateToNative(v Value, loc *time.Location) (time.Time, error) { - // Valid format string offsets for a DATE - // |DATE |10 - // |---------| - // "2006-01-02 00:00:00.000000" - return parseISOTime(v.ToString(), loc, 10, 10) -} - // EncodeSQL encodes the value into an SQL statement. Can be binary. func (v Value) EncodeSQL(b BinWriter) { switch { diff --git a/go/sqltypes/value_test.go b/go/sqltypes/value_test.go index 99f8566472e..f6360c8b5c4 100644 --- a/go/sqltypes/value_test.go +++ b/go/sqltypes/value_test.go @@ -18,7 +18,6 @@ package sqltypes import ( "math" - "reflect" "strings" "testing" "time" @@ -623,145 +622,6 @@ func DateValue(str string) Value { return TestValue(Date, str) } -func TestDatetimeToNative(t *testing.T) { - tcases := []struct { - val Value - loc *time.Location - out time.Time - err bool - }{{ - val: DatetimeValue("1899-08-24 17:20:00"), - out: time.Date(1899, 8, 24, 17, 20, 0, 0, time.UTC), - }, { - val: DatetimeValue("1952-03-11 01:02:03"), - loc: time.Local, - out: time.Date(1952, 3, 11, 1, 2, 3, 0, time.Local), - }, { - val: DatetimeValue("1952-03-11 01:02:03"), - loc: randomLocation, - out: time.Date(1952, 3, 11, 1, 2, 3, 0, randomLocation), - }, { - val: DatetimeValue("1952-03-11 01:02:03"), - loc: time.UTC, - out: time.Date(1952, 3, 11, 1, 2, 3, 0, time.UTC), - }, { - val: DatetimeValue("1899-08-24 17:20:00.000000"), - out: time.Date(1899, 8, 24, 17, 20, 0, 0, time.UTC), - }, { - val: DatetimeValue("1899-08-24 17:20:00.000001"), - out: time.Date(1899, 8, 24, 17, 20, 0, int(1*time.Microsecond), time.UTC), - }, { - val: DatetimeValue("1899-08-24 17:20:00.123456"), - out: time.Date(1899, 8, 24, 17, 20, 0, int(123456*time.Microsecond), time.UTC), - }, { - val: DatetimeValue("1899-08-24 17:20:00.222"), - out: time.Date(1899, 8, 24, 17, 20, 0, int(222*time.Millisecond), time.UTC), - }, { - val: DatetimeValue("1899-08-24 17:20:00.1234567"), - err: true, - }, { - val: DatetimeValue("1899-08-24 17:20:00.1"), - out: time.Date(1899, 8, 24, 17, 20, 0, int(100*time.Millisecond), time.UTC), - }, { - val: DatetimeValue("0000-00-00 00:00:00"), - out: time.Time{}, - }, { - val: DatetimeValue("0000-00-00 00:00:00.0"), - out: time.Time{}, - }, { - val: DatetimeValue("0000-00-00 00:00:00.000"), - out: time.Time{}, - }, { - val: DatetimeValue("0000-00-00 00:00:00.000000"), - out: time.Time{}, - }, { - val: DatetimeValue("0000-00-00 00:00:00.0000000"), - err: true, - }, { - val: DatetimeValue("1899-08-24T17:20:00.000000"), - err: true, - }, { - val: DatetimeValue("1899-02-31 17:20:00.000000"), - err: true, - }, { - val: DatetimeValue("1899-08-24 17:20:00."), - out: time.Date(1899, 8, 24, 17, 20, 0, 0, time.UTC), - }, { - val: DatetimeValue("0000-00-00 00:00:00.000001"), - err: true, - }, { - val: DatetimeValue("1899-08-24 17:20:00 +02:00"), - err: true, - }, { - val: DatetimeValue("1899-08-24"), - err: true, - }, { - val: DatetimeValue("This is not a valid timestamp"), - err: true, - }} - - for _, tcase := range tcases { - got, err := datetimeToNative(tcase.val, tcase.loc) - if tcase.err && err == nil { - t.Errorf("datetimeToNative(%v, %#v) succeeded; expected error", tcase.val, tcase.loc) - } - if !tcase.err && err != nil { - t.Errorf("datetimeToNative(%v, %#v) failed: %v", tcase.val, tcase.loc, err) - } - if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("datetimeToNative(%v, %#v): %v, want %v", tcase.val, tcase.loc, got, tcase.out) - } - } -} - -func TestDateToNative(t *testing.T) { - tcases := []struct { - val Value - loc *time.Location - out time.Time - err bool - }{{ - val: DateValue("1899-08-24"), - out: time.Date(1899, 8, 24, 0, 0, 0, 0, time.UTC), - }, { - val: DateValue("1952-03-11"), - loc: time.Local, - out: time.Date(1952, 3, 11, 0, 0, 0, 0, time.Local), - }, { - val: DateValue("1952-03-11"), - loc: randomLocation, - out: time.Date(1952, 3, 11, 0, 0, 0, 0, randomLocation), - }, { - val: DateValue("0000-00-00"), - out: time.Time{}, - }, { - val: DateValue("1899-02-31"), - err: true, - }, { - val: DateValue("1899-08-24 17:20:00"), - err: true, - }, { - val: DateValue("0000-00-00 00:00:00"), - err: true, - }, { - val: DateValue("This is not a valid timestamp"), - err: true, - }} - - for _, tcase := range tcases { - got, err := dateToNative(tcase.val, tcase.loc) - if tcase.err && err == nil { - t.Errorf("dateToNative(%v, %#v) succeeded; expected error", tcase.val, tcase.loc) - } - if !tcase.err && err != nil { - t.Errorf("dateToNative(%v, %#v) failed: %v", tcase.val, tcase.loc, err) - } - if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("dateToNative(%v, %#v): %v, want %v", tcase.val, tcase.loc, got, tcase.out) - } - } -} - func TestEncodeSQLStringBuilder(t *testing.T) { testcases := []struct { in Value diff --git a/go/streamlog/streamlog.go b/go/streamlog/streamlog.go index 40d33b840b4..00fc4dd4478 100644 --- a/go/streamlog/streamlog.go +++ b/go/streamlog/streamlog.go @@ -20,7 +20,7 @@ package streamlog import ( "fmt" "io" - rand "math/rand/v2" + "math/rand/v2" "net/http" "net/url" "os" @@ -47,40 +47,42 @@ var ( []string{"Log", "Subscriber"}) ) -var ( - redactDebugUIQueries bool - queryLogFilterTag string - queryLogRowThreshold uint64 - queryLogFormat = "text" - queryLogSampleRate float64 -) +const ( + // QueryLogFormatText is the format specifier for text querylog output + QueryLogFormatText = "text" -func GetRedactDebugUIQueries() bool { - return redactDebugUIQueries -} + // QueryLogFormatJSON is the format specifier for json querylog output + QueryLogFormatJSON = "json" -func SetRedactDebugUIQueries(newRedactDebugUIQueries bool) { - redactDebugUIQueries = newRedactDebugUIQueries -} + // QueryLogModeAll is the mode specifier for logging all queries + QueryLogModeAll = "all" -func SetQueryLogFilterTag(newQueryLogFilterTag string) { - queryLogFilterTag = newQueryLogFilterTag -} + // QueryLogModeError is the mode specifier for logging only queries that return an error + QueryLogModeError = "error" +) -func SetQueryLogRowThreshold(newQueryLogRowThreshold uint64) { - queryLogRowThreshold = newQueryLogRowThreshold +type QueryLogConfig struct { + RedactDebugUIQueries bool + FilterTag string + Format string + Mode string + RowThreshold uint64 + sampleRate float64 } -func SetQueryLogSampleRate(sampleRate float64) { - queryLogSampleRate = sampleRate +var queryLogConfigInstance = QueryLogConfig{ + Format: QueryLogFormatText, + Mode: QueryLogModeAll, } -func GetQueryLogFormat() string { - return queryLogFormat +func GetQueryLogConfig() QueryLogConfig { + return queryLogConfigInstance } -func SetQueryLogFormat(newQueryLogFormat string) { - queryLogFormat = newQueryLogFormat +func NewQueryLogConfigForTest() QueryLogConfig { + return QueryLogConfig{ + Format: QueryLogFormatText, + } } func init() { @@ -91,28 +93,23 @@ func init() { func registerStreamLogFlags(fs *pflag.FlagSet) { // RedactDebugUIQueries controls whether full queries and bind variables are suppressed from debug UIs. - fs.BoolVar(&redactDebugUIQueries, "redact-debug-ui-queries", redactDebugUIQueries, "redact full queries and bind variables from debug UI") + fs.BoolVar(&queryLogConfigInstance.RedactDebugUIQueries, "redact-debug-ui-queries", queryLogConfigInstance.RedactDebugUIQueries, "redact full queries and bind variables from debug UI") // QueryLogFormat controls the format of the query log (either text or json) - fs.StringVar(&queryLogFormat, "querylog-format", queryLogFormat, "format for query logs (\"text\" or \"json\")") + fs.StringVar(&queryLogConfigInstance.Format, "querylog-format", queryLogConfigInstance.Format, "format for query logs (\"text\" or \"json\")") // QueryLogFilterTag contains an optional string that must be present in the query for it to be logged - fs.StringVar(&queryLogFilterTag, "querylog-filter-tag", queryLogFilterTag, "string that must be present in the query for it to be logged; if using a value as the tag, you need to disable query normalization") + fs.StringVar(&queryLogConfigInstance.FilterTag, "querylog-filter-tag", queryLogConfigInstance.FilterTag, "string that must be present in the query for it to be logged; if using a value as the tag, you need to disable query normalization") // QueryLogRowThreshold only log queries returning or affecting this many rows - fs.Uint64Var(&queryLogRowThreshold, "querylog-row-threshold", queryLogRowThreshold, "Number of rows a query has to return or affect before being logged; not useful for streaming queries. 0 means all queries will be logged.") + fs.Uint64Var(&queryLogConfigInstance.RowThreshold, "querylog-row-threshold", queryLogConfigInstance.RowThreshold, "Number of rows a query has to return or affect before being logged; not useful for streaming queries. 0 means all queries will be logged.") // QueryLogSampleRate causes a sample of queries to be logged - fs.Float64Var(&queryLogSampleRate, "querylog-sample-rate", queryLogSampleRate, "Sample rate for logging queries. Value must be between 0.0 (no logging) and 1.0 (all queries)") -} - -const ( - // QueryLogFormatText is the format specifier for text querylog output - QueryLogFormatText = "text" + fs.Float64Var(&queryLogConfigInstance.sampleRate, "querylog-sample-rate", queryLogConfigInstance.sampleRate, "Sample rate for logging queries. Value must be between 0.0 (no logging) and 1.0 (all queries)") - // QueryLogFormatJSON is the format specifier for json querylog output - QueryLogFormatJSON = "json" -) + // QueryLogMode controls the mode for logging queries (all or error) + fs.StringVar(&queryLogConfigInstance.Mode, "querylog-mode", queryLogConfigInstance.Mode, `Mode for logging queries. "error" will only log queries that return an error. Otherwise all queries will be logged.`) +} // StreamLogger is a non-blocking broadcaster of messages. // Subscribers can use channels or HTTP. @@ -257,27 +254,30 @@ func GetFormatter[T any](logger *StreamLogger[T]) LogFormatter { } } -// shouldSampleQuery returns true if a query should be sampled based on queryLogSampleRate -func shouldSampleQuery() bool { - if queryLogSampleRate <= 0 { +// shouldSampleQuery returns true if a query should be sampled based on sampleRate +func (qlConfig QueryLogConfig) shouldSampleQuery() bool { + if qlConfig.sampleRate <= 0 { return false - } else if queryLogSampleRate >= 1 { + } else if qlConfig.sampleRate >= 1 { return true } - return rand.Float64() <= queryLogSampleRate + return rand.Float64() <= qlConfig.sampleRate } // ShouldEmitLog returns whether the log with the given SQL query // should be emitted or filtered -func ShouldEmitLog(sql string, rowsAffected, rowsReturned uint64) bool { - if shouldSampleQuery() { +func (qlConfig QueryLogConfig) ShouldEmitLog(sql string, rowsAffected, rowsReturned uint64, hasError bool) bool { + if qlConfig.shouldSampleQuery() { return true } - if queryLogRowThreshold > max(rowsAffected, rowsReturned) && queryLogFilterTag == "" { + if qlConfig.RowThreshold > max(rowsAffected, rowsReturned) && qlConfig.FilterTag == "" { return false } - if queryLogFilterTag != "" { - return strings.Contains(sql, queryLogFilterTag) + if qlConfig.FilterTag != "" { + return strings.Contains(sql, qlConfig.FilterTag) + } + if qlConfig.Mode == QueryLogModeError { + return hasError } return true } diff --git a/go/streamlog/streamlog_test.go b/go/streamlog/streamlog_test.go index c1321c92a94..8256ada479e 100644 --- a/go/streamlog/streamlog_test.go +++ b/go/streamlog/streamlog_test.go @@ -266,40 +266,29 @@ func TestFile(t *testing.T) { } func TestShouldSampleQuery(t *testing.T) { - queryLogSampleRate = -1 - assert.False(t, shouldSampleQuery()) + qlConfig := QueryLogConfig{sampleRate: -1} + assert.False(t, qlConfig.shouldSampleQuery()) - queryLogSampleRate = 0 - assert.False(t, shouldSampleQuery()) + qlConfig.sampleRate = 0 + assert.False(t, qlConfig.shouldSampleQuery()) - // for test coverage, can't test a random result - queryLogSampleRate = 0.5 - shouldSampleQuery() + qlConfig.sampleRate = 1.0 + assert.True(t, qlConfig.shouldSampleQuery()) - queryLogSampleRate = 1.0 - assert.True(t, shouldSampleQuery()) - - queryLogSampleRate = 100.0 - assert.True(t, shouldSampleQuery()) + qlConfig.sampleRate = 100.0 + assert.True(t, qlConfig.shouldSampleQuery()) } func TestShouldEmitLog(t *testing.T) { - origQueryLogFilterTag := queryLogFilterTag - origQueryLogRowThreshold := queryLogRowThreshold - origQueryLogSampleRate := queryLogSampleRate - defer func() { - SetQueryLogFilterTag(origQueryLogFilterTag) - SetQueryLogRowThreshold(origQueryLogRowThreshold) - SetQueryLogSampleRate(origQueryLogSampleRate) - }() - tests := []struct { sql string qLogFilterTag string qLogRowThreshold uint64 qLogSampleRate float64 + qLogMode string rowsAffected uint64 rowsReturned uint64 + errored bool ok bool }{ { @@ -356,43 +345,33 @@ func TestShouldEmitLog(t *testing.T) { rowsReturned: 17, ok: true, }, + { + sql: "log only error - no error", + qLogMode: "error", + errored: false, + ok: false, + }, + { + sql: "log only error - errored", + qLogMode: "error", + errored: true, + ok: true, + }, } for _, tt := range tests { t.Run(tt.sql, func(t *testing.T) { - SetQueryLogFilterTag(tt.qLogFilterTag) - SetQueryLogRowThreshold(tt.qLogRowThreshold) - SetQueryLogSampleRate(tt.qLogSampleRate) - - require.Equal(t, tt.ok, ShouldEmitLog(tt.sql, tt.rowsAffected, tt.rowsReturned)) + qlConfig := QueryLogConfig{ + FilterTag: tt.qLogFilterTag, + RowThreshold: tt.qLogRowThreshold, + sampleRate: tt.qLogSampleRate, + Mode: tt.qLogMode, + } + require.Equal(t, tt.ok, qlConfig.ShouldEmitLog(tt.sql, tt.rowsAffected, tt.rowsReturned, tt.errored)) }) } } -func BenchmarkShouldEmitLog(b *testing.B) { - b.Run("default", func(b *testing.B) { - SetQueryLogSampleRate(0.0) - for i := 0; i < b.N; i++ { - ShouldEmitLog("select * from test where user='someone'", 0, 123) - } - }) - b.Run("filter_tag", func(b *testing.B) { - SetQueryLogSampleRate(0.0) - SetQueryLogFilterTag("LOG_QUERY") - defer SetQueryLogFilterTag("") - for i := 0; i < b.N; i++ { - ShouldEmitLog("select /* LOG_QUERY=1 */ * from test where user='someone'", 0, 123) - } - }) - b.Run("50%_sample_rate", func(b *testing.B) { - SetQueryLogSampleRate(0.5) - defer SetQueryLogSampleRate(0.0) - for i := 0; i < b.N; i++ { - ShouldEmitLog("select * from test where user='someone'", 0, 123) - } - }) -} - func TestGetFormatter(t *testing.T) { tests := []struct { name string diff --git a/go/sync2/consolidator.go b/go/sync2/consolidator.go index 401daaef1f1..df900625abb 100644 --- a/go/sync2/consolidator.go +++ b/go/sync2/consolidator.go @@ -40,6 +40,7 @@ type PendingResult interface { SetResult(*sqltypes.Result) Result() *sqltypes.Result Wait() + AddWaiterCounter(int64) *int64 } type consolidator struct { @@ -77,6 +78,7 @@ func (co *consolidator) Create(query string) (PendingResult, bool) { defer co.mu.Unlock() var r *pendingResult if r, ok := co.queries[query]; ok { + r.AddWaiterCounter(1) return r, false } r = &pendingResult{consolidator: co, query: query} @@ -122,17 +124,23 @@ func (rs *pendingResult) Wait() { rs.executing.RLock() } +func (rs *pendingResult) AddWaiterCounter(c int64) *int64 { + atomic.AddInt64(rs.consolidator.totalWaiterCount, c) + return rs.consolidator.totalWaiterCount +} + // ConsolidatorCache is a thread-safe object used for counting how often recent // queries have been consolidated. // It is also used by the txserializer package to count how often transactions // have been queued and had to wait because they targeted the same row (range). type ConsolidatorCache struct { *cache.LRUCache[*ccount] + totalWaiterCount *int64 } // NewConsolidatorCache creates a new cache with the given capacity. func NewConsolidatorCache(capacity int64) *ConsolidatorCache { - return &ConsolidatorCache{cache.NewLRUCache[*ccount](capacity)} + return &ConsolidatorCache{cache.NewLRUCache[*ccount](capacity), new(int64)} } // Record increments the count for "query" by 1. diff --git a/go/sync2/consolidator_test.go b/go/sync2/consolidator_test.go index 132a253ba29..5437bb335a6 100644 --- a/go/sync2/consolidator_test.go +++ b/go/sync2/consolidator_test.go @@ -18,11 +18,42 @@ package sync2 import ( "reflect" + "sync" "testing" "vitess.io/vitess/go/sqltypes" ) +func TestAddWaiterCount(t *testing.T) { + con := NewConsolidator() + sql := "select * from SomeTable" + pr, _ := con.Create(sql) + var wgAdd sync.WaitGroup + var wgSub sync.WaitGroup + + var concurrent = 1000 + + for i := 0; i < concurrent; i++ { + wgAdd.Add(1) + wgSub.Add(1) + go func() { + defer wgAdd.Done() + pr.AddWaiterCounter(1) + }() + go func() { + defer wgSub.Done() + pr.AddWaiterCounter(-1) + }() + } + + wgAdd.Wait() + wgSub.Wait() + + if *pr.AddWaiterCounter(0) != 0 { + t.Fatalf("Expect 0 totalWaiterCount but got: %v", *pr.AddWaiterCounter(0)) + } +} + func TestConsolidator(t *testing.T) { con := NewConsolidator() sql := "select * from SomeTable" diff --git a/go/sync2/fake_consolidator.go b/go/sync2/fake_consolidator.go index 64c59e78a5a..aadee1d37ce 100644 --- a/go/sync2/fake_consolidator.go +++ b/go/sync2/fake_consolidator.go @@ -112,3 +112,8 @@ func (fr *FakePendingResult) SetResult(result *sqltypes.Result) { func (fr *FakePendingResult) Wait() { fr.WaitCalls++ } + +// AddWaiterCounter is currently a no-op. +func (fr *FakePendingResult) AddWaiterCounter(int64) *int64 { + return new(int64) +} diff --git a/go/test/endtoend/backup/s3/s3_builtin_test.go b/go/test/endtoend/backup/s3/s3_builtin_test.go new file mode 100644 index 00000000000..9c83e5f8fec --- /dev/null +++ b/go/test/endtoend/backup/s3/s3_builtin_test.go @@ -0,0 +1,434 @@ +/* +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 s3 + +import ( + "context" + "io" + "os" + "os/exec" + "path" + "strconv" + "strings" + "testing" + "time" + + "log" + + "github.com/minio/minio-go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/mysqlctl/backupstats" + "vitess.io/vitess/go/vt/mysqlctl/blackbox" + "vitess.io/vitess/go/vt/mysqlctl/s3backupstorage" +) + +/* + These tests use Minio to emulate AWS S3. It allows us to run the tests on + GitHub Actions without having the security burden of carrying out AWS secrets + in our GitHub repo. + + Minio is almost a drop-in replacement for AWS S3, if you want to run these + tests against a true AWS S3 Bucket, you can do so by not running the TestMain + and setting the 'AWS_*' environment variables to your own values. + + This package and file are named 'endtoend', but it's more an integration test. + However, we don't want our CI infra to mistake this for a regular unit-test, + hence the rename to 'endtoend'. +*/ + +func TestMain(m *testing.M) { + f := func() int { + minioPath, err := exec.LookPath("minio") + if err != nil { + log.Fatalf("minio binary not found: %v", err) + } + + dataDir, err := os.MkdirTemp("", "") + if err != nil { + log.Fatalf("could not create temporary directory: %v", err) + } + err = os.MkdirAll(dataDir, 0755) + if err != nil { + log.Fatalf("failed to create MinIO data directory: %v", err) + } + + cmd := exec.Command(minioPath, "server", dataDir, "--console-address", ":9001") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + err = cmd.Start() + if err != nil { + log.Fatalf("failed to start MinIO: %v", err) + } + defer func() { + cmd.Process.Kill() + }() + + // Local MinIO credentials + accessKey := "minioadmin" + secretKey := "minioadmin" + minioEndpoint := "http://localhost:9000" + bucketName := "test-bucket" + region := "us-east-1" + + client, err := minio.New("localhost:9000", accessKey, secretKey, false) + if err != nil { + log.Fatalf("failed to create MinIO client: %v", err) + } + waitForMinio(client) + + err = client.MakeBucket(bucketName, region) + if err != nil { + log.Fatalf("failed to create test bucket: %v", err) + } + + // Same env variables that are used between AWS S3 and Minio + os.Setenv("AWS_ACCESS_KEY_ID", accessKey) + os.Setenv("AWS_SECRET_ACCESS_KEY", secretKey) + os.Setenv("AWS_BUCKET", bucketName) + os.Setenv("AWS_ENDPOINT", minioEndpoint) + os.Setenv("AWS_REGION", region) + + return m.Run() + } + + os.Exit(f()) +} + +func waitForMinio(client *minio.Client) { + for i := 0; i < 60; i++ { + _, err := client.ListBuckets() + if err == nil { + return + } + time.Sleep(1 * time.Second) + } + log.Fatalf("MinIO server did not become ready in time") +} + +func checkEnvForS3(t *testing.T) { + // We never want to skip the tests if we are running on CI. + // We will always run these tests on CI with the TestMain and Minio. + // There should not be a need to skip the tests due to missing ENV vars. + if os.Getenv("GITHUB_ACTIONS") != "" { + return + } + + envRequired := []string{ + "AWS_ACCESS_KEY_ID", + "AWS_SECRET_ACCESS_KEY", + "AWS_BUCKET", + "AWS_ENDPOINT", + "AWS_REGION", + } + + var missing []string + for _, s := range envRequired { + if os.Getenv(s) == "" { + missing = append(missing, s) + } + } + if len(missing) > 0 { + t.Skipf("missing AWS secrets to run this test: please set: %s", strings.Join(missing, ", ")) + } +} + +type backupTestConfig struct { + concurrency int + addFileReturnFn func(s3 *s3backupstorage.S3BackupHandle, ctx context.Context, filename string, filesize int64, firstAdd bool) (io.WriteCloser, error) + checkCleanupError bool + expectedResult mysqlctl.BackupResult + expectedStats blackbox.StatSummary +} + +func runBackupTest(t *testing.T, cfg backupTestConfig) { + checkEnvForS3(t) + s3backupstorage.InitFlag(s3backupstorage.FakeConfig{ + Region: os.Getenv("AWS_REGION"), + Endpoint: os.Getenv("AWS_ENDPOINT"), + Bucket: os.Getenv("AWS_BUCKET"), + ForcePath: true, + }) + + ctx := context.Background() + backupRoot, keyspace, shard, ts := blackbox.SetupCluster(ctx, t, 2, 2) + + be := &mysqlctl.BuiltinBackupEngine{} + + // Configure a tight deadline to force a timeout + oldDeadline := blackbox.SetBuiltinBackupMysqldDeadline(time.Second) + defer blackbox.SetBuiltinBackupMysqldDeadline(oldDeadline) + + fakeStats := backupstats.NewFakeStats() + logger := logutil.NewMemoryLogger() + + bh, err := s3backupstorage.NewFakeS3BackupHandle(ctx, t.Name(), time.Now().Format(mysqlctl.BackupTimestampFormat), logger, fakeStats) + require.NoError(t, err) + t.Cleanup(func() { + err := bh.AbortBackup(ctx) + if cfg.checkCleanupError { + require.NoError(t, err) + } + }) + bh.AddFileReturnF = cfg.addFileReturnFn + + // Spin up a fake daemon to be used in backups. It needs to be allowed to receive: + // "STOP REPLICA", "START REPLICA", in that order. + fakedb := fakesqldb.New(t) + defer fakedb.Close() + mysqld := mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + backupResult, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logger, + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + Concurrency: cfg.concurrency, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + Stats: fakeStats, + MysqlShutdownTimeout: blackbox.MysqlShutdownTimeout, + }, bh) + + require.Equal(t, cfg.expectedResult, backupResult) + switch cfg.expectedResult { + case mysqlctl.BackupUsable: + require.NoError(t, err) + case mysqlctl.BackupUnusable, mysqlctl.BackupEmpty: + require.Error(t, err) + } + + ss := blackbox.GetStats(fakeStats) + require.Equal(t, cfg.expectedStats.DestinationCloseStats, ss.DestinationCloseStats) + require.Equal(t, cfg.expectedStats.DestinationOpenStats, ss.DestinationOpenStats) + require.Equal(t, cfg.expectedStats.DestinationWriteStats, ss.DestinationWriteStats) + require.Equal(t, cfg.expectedStats.SourceCloseStats, ss.SourceCloseStats) + require.Equal(t, cfg.expectedStats.SourceOpenStats, ss.SourceOpenStats) + require.Equal(t, cfg.expectedStats.SourceReadStats, ss.SourceReadStats) +} + +func TestExecuteBackupS3FailEachFileOnce(t *testing.T) { + runBackupTest(t, backupTestConfig{ + concurrency: 2, + + // Modify the fake S3 storage to always fail when trying to write a file for the first time + addFileReturnFn: s3backupstorage.FailFirstWrite, + checkCleanupError: true, + expectedResult: mysqlctl.BackupUsable, + + // Even though we have 4 files, we expect '8' for all the values below as we re-do every file once. + expectedStats: blackbox.StatSummary{ + DestinationCloseStats: 8, + DestinationOpenStats: 8, + DestinationWriteStats: 8, + SourceCloseStats: 8, + SourceOpenStats: 8, + SourceReadStats: 8, + }, + }) +} + +func TestExecuteBackupS3FailEachFileTwice(t *testing.T) { + runBackupTest(t, backupTestConfig{ + concurrency: 1, + + // Modify the fake S3 storage to always fail when trying to write a file for the first time + addFileReturnFn: s3backupstorage.FailAllWrites, + + // If the code works as expected by this test, no files will be created on S3 and AbortBackup will + // fail, for this reason, let's not check the error return. + // We still call AbortBackup anyway in the event that the code is not behaving as expected and some + // files were created by mistakes, we delete them. + checkCleanupError: false, + expectedResult: mysqlctl.BackupUnusable, + + // All stats here must be equal to 5, we have four files, we go each of them, they all fail. + // The logic decides to retry each file once, we retry the first failed file, it fails again + // but since it has reached the limit of retries, the backup will fail anyway, thus we don't + // retry the other 3 files. + expectedStats: blackbox.StatSummary{ + DestinationCloseStats: 5, + DestinationOpenStats: 5, + DestinationWriteStats: 5, + SourceCloseStats: 5, + SourceOpenStats: 5, + SourceReadStats: 5, + }, + }) +} + +type restoreTestConfig struct { + readFileReturnFn func(s3 *s3backupstorage.S3BackupHandle, ctx context.Context, filename string, firstRead bool) (io.ReadCloser, error) + expectSuccess bool + expectedStats blackbox.StatSummary +} + +func runRestoreTest(t *testing.T, cfg restoreTestConfig) { + checkEnvForS3(t) + s3backupstorage.InitFlag(s3backupstorage.FakeConfig{ + Region: os.Getenv("AWS_REGION"), + Endpoint: os.Getenv("AWS_ENDPOINT"), + Bucket: os.Getenv("AWS_BUCKET"), + ForcePath: true, + }) + + ctx := context.Background() + backupRoot, keyspace, shard, ts := blackbox.SetupCluster(ctx, t, 2, 2) + + fakeStats := backupstats.NewFakeStats() + logger := logutil.NewMemoryLogger() + + be := &mysqlctl.BuiltinBackupEngine{} + dirName := time.Now().Format(mysqlctl.BackupTimestampFormat) + name := t.Name() + "-" + strconv.Itoa(int(time.Now().Unix())) + bh, err := s3backupstorage.NewFakeS3BackupHandle(ctx, name, dirName, logger, fakeStats) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, bh.AbortBackup(ctx)) + }) + + // Spin up a fake daemon to be used in backups. It needs to be allowed to receive: + // "STOP REPLICA", "START REPLICA", in that order. + fakedb := fakesqldb.New(t) + defer fakedb.Close() + mysqld := mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + backupResult, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logutil.NewConsoleLogger(), + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + Stats: backupstats.NewFakeStats(), + Concurrency: 1, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: blackbox.MysqlShutdownTimeout, + }, bh) + + require.NoError(t, err) + require.Equal(t, mysqlctl.BackupUsable, backupResult) + + // Backup is done, let's move on to the restore now + + restoreBh, err := s3backupstorage.NewFakeS3RestoreHandle(ctx, name, logger, fakeStats) + require.NoError(t, err) + restoreBh.ReadFileReturnF = cfg.readFileReturnFn + + fakedb = fakesqldb.New(t) + defer fakedb.Close() + mysqld = mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + restoreParams := mysqlctl.RestoreParams{ + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + BinLogPath: path.Join(backupRoot, "binlog"), + RelayLogPath: path.Join(backupRoot, "relaylog"), + RelayLogIndexPath: path.Join(backupRoot, "relaylogindex"), + RelayLogInfoPath: path.Join(backupRoot, "relayloginfo"), + }, + Logger: logger, + Mysqld: mysqld, + Concurrency: 1, + HookExtraEnv: map[string]string{}, + DeleteBeforeRestore: false, + DbName: "test", + Keyspace: "test", + Shard: "-", + StartTime: time.Now(), + RestoreToPos: replication.Position{}, + RestoreToTimestamp: time.Time{}, + DryRun: false, + Stats: fakeStats, + MysqlShutdownTimeout: blackbox.MysqlShutdownTimeout, + } + + // Successful restore. + bm, err := be.ExecuteRestore(ctx, restoreParams, restoreBh) + + if cfg.expectSuccess { + assert.NoError(t, err) + assert.NotNil(t, bm) + } else { + assert.Error(t, err) + } + + ss := blackbox.GetStats(fakeStats) + require.Equal(t, cfg.expectedStats.DestinationCloseStats, ss.DestinationCloseStats) + require.Equal(t, cfg.expectedStats.DestinationOpenStats, ss.DestinationOpenStats) + require.Equal(t, cfg.expectedStats.DestinationWriteStats, ss.DestinationWriteStats) + require.Equal(t, cfg.expectedStats.SourceCloseStats, ss.SourceCloseStats) + require.Equal(t, cfg.expectedStats.SourceOpenStats, ss.SourceOpenStats) + require.Equal(t, cfg.expectedStats.SourceReadStats, ss.SourceReadStats) +} + +func TestExecuteRestoreS3FailEachFileOnce(t *testing.T) { + runRestoreTest(t, restoreTestConfig{ + readFileReturnFn: s3backupstorage.FailFirstRead, + expectSuccess: true, + expectedStats: blackbox.StatSummary{ + DestinationCloseStats: 8, + DestinationOpenStats: 8, + DestinationWriteStats: 4, // 4, because on the first attempt, we fail to read before writing to the filesystem + SourceCloseStats: 8, + SourceOpenStats: 8, + SourceReadStats: 8, + }, + }) +} + +func TestExecuteRestoreS3FailEachFileTwice(t *testing.T) { + runRestoreTest(t, restoreTestConfig{ + readFileReturnFn: s3backupstorage.FailAllReadExpectManifest, + expectSuccess: false, + + // Everything except destination writes must be equal to 5: + // +1 for every file on the first attempt (= 4), and +1 for the first file we try for the second time. + // Since we fail early as soon as a second-attempt-file fails, we won't see a value above 5. + expectedStats: blackbox.StatSummary{ + DestinationCloseStats: 5, + DestinationOpenStats: 5, + DestinationWriteStats: 0, // 0, because on the both attempts, we fail to read before writing to the filesystem + SourceCloseStats: 5, + SourceOpenStats: 5, + SourceReadStats: 5, + }, + }) +} diff --git a/go/test/endtoend/backup/vtbackup/backup_only_test.go b/go/test/endtoend/backup/vtbackup/backup_only_test.go index 4e018986100..0ad25301af0 100644 --- a/go/test/endtoend/backup/vtbackup/backup_only_test.go +++ b/go/test/endtoend/backup/vtbackup/backup_only_test.go @@ -47,6 +47,55 @@ var ( ) Engine=InnoDB;` ) +func TestFailingReplication(t *testing.T) { + prepareCluster(t) + + // Run the entire backup test + firstBackupTest(t, false) + + // Insert one more row, the primary will be ahead of the last backup + _, err := primary.VttabletProcess.QueryTablet("insert into vt_insert_test (msg) values ('test_failure')", keyspaceName, true) + require.NoError(t, err) + + // Disable replication from the primary by removing the grants to 'vt_repl'. + _, err = primary.VttabletProcess.QueryTablet("REVOKE REPLICATION SLAVE ON *.* FROM 'vt_repl'@'%';", keyspaceName, true) + require.NoError(t, err) + _, err = primary.VttabletProcess.QueryTablet("FLUSH PRIVILEGES;", keyspaceName, true) + require.NoError(t, err) + + // Take a backup with vtbackup: the process should fail entirely as it cannot replicate from the primary. + _, err = startVtBackup(t, false, false, false) + require.Error(t, err) + + // keep in mind how many backups we have right now + backups, err := listBackups(shardKsName) + require.NoError(t, err) + + // In 30 seconds, grant the replication permission again to 'vt_repl'. + // This will mean that vtbackup should fail to replicate for ~30 seconds, until we grant the permission again. + go func() { + <-time.After(30 * time.Second) + _, err = primary.VttabletProcess.QueryTablet("GRANT REPLICATION SLAVE ON *.* TO 'vt_repl'@'%';", keyspaceName, true) + require.NoError(t, err) + _, err = primary.VttabletProcess.QueryTablet("FLUSH PRIVILEGES;", keyspaceName, true) + require.NoError(t, err) + }() + + startTime := time.Now() + // this will initially be stuck trying to replicate from the primary, and once we re-grant the permission in + // the goroutine above, the process will work and complete successfully. + _ = vtBackup(t, false, false, false) + + require.GreaterOrEqual(t, time.Since(startTime).Seconds(), float64(30)) + + verifyBackupCount(t, shardKsName, len(backups)+1) + + removeBackups(t) + verifyBackupCount(t, shardKsName, 0) + + tearDown(t, true) +} + func TestTabletInitialBackup(t *testing.T) { // Test Initial Backup Flow // TestTabletInitialBackup will: @@ -58,8 +107,16 @@ func TestTabletInitialBackup(t *testing.T) { // - Take a Second Backup // - Bring up a second replica, and restore from the second backup // - list the backups, remove them - defer cluster.PanicHandler(t) + prepareCluster(t) + + // Run the entire backup test + firstBackupTest(t, true) + + tearDown(t, true) +} + +func prepareCluster(t *testing.T) { waitForReplicationToCatchup([]cluster.Vttablet{*replica1, *replica2}) dataPointReader := vtBackup(t, true, false, false) @@ -85,11 +142,6 @@ func TestTabletInitialBackup(t *testing.T) { "TabletExternallyReparented", primary.Alias) require.NoError(t, err) restore(t, replica1, "replica", "SERVING") - - // Run the entire backup test - firstBackupTest(t, "replica") - - tearDown(t, true) } func TestTabletBackupOnly(t *testing.T) { @@ -102,19 +154,18 @@ func TestTabletBackupOnly(t *testing.T) { // - Take a Second Backup // - Bring up a second replica, and restore from the second backup // - list the backups, remove them - defer cluster.PanicHandler(t) // Reset the tablet object values in order on init tablet in the next step. primary.VttabletProcess.ServingStatus = "NOT_SERVING" replica1.VttabletProcess.ServingStatus = "NOT_SERVING" initTablets(t, true, true) - firstBackupTest(t, "replica") + firstBackupTest(t, true) tearDown(t, false) } -func firstBackupTest(t *testing.T, tabletType string) { +func firstBackupTest(t *testing.T, removeBackup bool) { // Test First Backup flow. // // firstBackupTest will: @@ -170,11 +221,13 @@ func firstBackupTest(t *testing.T, tabletType string) { // check the new replica has the data cluster.VerifyRowsInTablet(t, replica2, keyspaceName, 2) - removeBackups(t) - verifyBackupCount(t, shardKsName, 0) + if removeBackup { + removeBackups(t) + verifyBackupCount(t, shardKsName, 0) + } } -func vtBackup(t *testing.T, initialBackup bool, restartBeforeBackup, disableRedoLog bool) *opentsdb.DataPointReader { +func startVtBackup(t *testing.T, initialBackup bool, restartBeforeBackup, disableRedoLog bool) (*os.File, error) { mysqlSocket, err := os.CreateTemp("", "vtbackup_test_mysql.sock") require.NoError(t, err) defer os.Remove(mysqlSocket.Name()) @@ -209,9 +262,19 @@ func vtBackup(t *testing.T, initialBackup bool, restartBeforeBackup, disableRedo log.Infof("starting backup tablet %s", time.Now()) err = localCluster.StartVtbackup(newInitDBFile, initialBackup, keyspaceName, shardName, cell, extraArgs...) - require.NoError(t, err) + if err != nil { + return nil, err + } f, err := os.OpenFile(statsPath, os.O_RDONLY, 0) + if err != nil { + return nil, err + } + return f, nil +} + +func vtBackup(t *testing.T, initialBackup bool, restartBeforeBackup, disableRedoLog bool) *opentsdb.DataPointReader { + f, err := startVtBackup(t, initialBackup, restartBeforeBackup, disableRedoLog) require.NoError(t, err) return opentsdb.NewDataPointReader(f) } @@ -224,11 +287,8 @@ func verifyBackupCount(t *testing.T, shardKsName string, expected int) []string } func listBackups(shardKsName string) ([]string, error) { - backups, err := localCluster.VtctlProcess.ExecuteCommandWithOutput( - "--backup_storage_implementation", "file", - "--file_backup_storage_root", - path.Join(os.Getenv("VTDATAROOT"), "tmp", "backupstorage"), - "ListBackups", shardKsName, + backups, err := localCluster.VtctldClientProcess.ExecuteCommandWithOutput( + "GetBackups", shardKsName, ) if err != nil { return nil, err @@ -248,10 +308,7 @@ func removeBackups(t *testing.T) { backups, err := listBackups(shardKsName) require.NoError(t, err) for _, backup := range backups { - _, err := localCluster.VtctlProcess.ExecuteCommandWithOutput( - "--backup_storage_implementation", "file", - "--file_backup_storage_root", - path.Join(os.Getenv("VTDATAROOT"), "tmp", "backupstorage"), + _, err := localCluster.VtctldClientProcess.ExecuteCommandWithOutput( "RemoveBackup", shardKsName, backup, ) require.NoError(t, err) diff --git a/go/test/endtoend/backup/vtbackup/main_test.go b/go/test/endtoend/backup/vtbackup/main_test.go index 367956c9827..54003416776 100644 --- a/go/test/endtoend/backup/vtbackup/main_test.go +++ b/go/test/endtoend/backup/vtbackup/main_test.go @@ -52,7 +52,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode, err := func() (int, error) { @@ -77,7 +76,7 @@ func TestMain(m *testing.M) { }, } shard := &localCluster.Keyspaces[0].Shards[0] - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", localCluster.VtctldProcess.GrpcPort, localCluster.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(localCluster.VtctldProcess.GrpcPort, localCluster.TopoPort, "localhost", localCluster.TmpDirectory) _, err = vtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", keyspaceName, "--durability-policy=semi_sync") if err != nil { return 1, err diff --git a/go/test/endtoend/backup/vtctlbackup/backup_utils.go b/go/test/endtoend/backup/vtctlbackup/backup_utils.go index 7c03b776c74..afa5023a047 100644 --- a/go/test/endtoend/backup/vtctlbackup/backup_utils.go +++ b/go/test/endtoend/backup/vtctlbackup/backup_utils.go @@ -254,7 +254,7 @@ func LaunchCluster(setupType int, streamMode string, stripes int, cDetails *Comp if err := localCluster.InitTablet(replica2, keyspaceName, shard.Name); err != nil { return 1, err } - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", localCluster.VtctldProcess.GrpcPort, localCluster.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(localCluster.VtctldProcess.GrpcPort, localCluster.TopoPort, "localhost", localCluster.TmpDirectory) _, err = vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync") if err != nil { return 1, err @@ -405,7 +405,6 @@ func TestBackup(t *testing.T, setupType int, streamMode string, stripes int, cDe }, // } - defer cluster.PanicHandler(t) // setup cluster for the testing code, err := LaunchCluster(setupType, streamMode, stripes, cDetails) require.Nilf(t, err, "setup failed with status code %d", code) @@ -1507,7 +1506,6 @@ func getLastBackup(t *testing.T) string { func TestBackupEngineSelector(t *testing.T) { defer setDefaultCommonArgs() - defer cluster.PanicHandler(t) // launch the custer with xtrabackup as the default engine code, err := LaunchCluster(XtraBackup, "xbstream", 0, &CompressionDetails{CompressorEngineName: "pgzip"}) @@ -1548,7 +1546,6 @@ func TestBackupEngineSelector(t *testing.T) { func TestRestoreAllowedBackupEngines(t *testing.T) { defer setDefaultCommonArgs() - defer cluster.PanicHandler(t) backupMsg := "right after xtrabackup backup" diff --git a/go/test/endtoend/backup/vtctlbackup/pitr_test_framework.go b/go/test/endtoend/backup/vtctlbackup/pitr_test_framework.go index 4c84c3e63bc..1b04dbc7aab 100644 --- a/go/test/endtoend/backup/vtctlbackup/pitr_test_framework.go +++ b/go/test/endtoend/backup/vtctlbackup/pitr_test_framework.go @@ -95,7 +95,6 @@ func waitForReplica(t *testing.T, replicaIndex int) int { // in between, it makes writes to the database, and takes notes: what data was available in what backup. // It then restores each and every one of those backups, in random order, and expects to find the specific data associated with the backup. func ExecTestIncrementalBackupAndRestoreToPos(t *testing.T, tcase *PITRTestCase) { - defer cluster.PanicHandler(t) t.Run(tcase.Name, func(t *testing.T) { // setup cluster for the testing @@ -339,7 +338,6 @@ func ExecTestIncrementalBackupAndRestoreToPos(t *testing.T, tcase *PITRTestCase) // ExecTestIncrementalBackupAndRestoreToPos func ExecTestIncrementalBackupAndRestoreToTimestamp(t *testing.T, tcase *PITRTestCase) { - defer cluster.PanicHandler(t) var lastInsertedRowTimestamp time.Time insertRowOnPrimary := func(t *testing.T, hint string) { @@ -605,7 +603,6 @@ func ExecTestIncrementalBackupAndRestoreToTimestamp(t *testing.T, tcase *PITRTes // Specifically, it's designed to test how incremental backups are taken by interleaved replicas, so that they successfully build on // one another. func ExecTestIncrementalBackupOnTwoTablets(t *testing.T, tcase *PITRTestCase) { - defer cluster.PanicHandler(t) t.Run(tcase.Name, func(t *testing.T) { // setup cluster for the testing diff --git a/go/test/endtoend/cellalias/cell_alias_test.go b/go/test/endtoend/cellalias/cell_alias_test.go index 07e8d687f4e..ef003754655 100644 --- a/go/test/endtoend/cellalias/cell_alias_test.go +++ b/go/test/endtoend/cellalias/cell_alias_test.go @@ -90,7 +90,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -110,12 +109,12 @@ func TestMain(m *testing.M) { if err != nil { return 1, err } - err = localCluster.VtctlProcess.AddCellInfo(cell2) + err = localCluster.VtctldClientProcess.AddCellInfo(cell2) if err != nil { return 1, err } - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", localCluster.VtctldProcess.GrpcPort, localCluster.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(localCluster.VtctldProcess.GrpcPort, localCluster.TopoPort, "localhost", localCluster.TmpDirectory) _, err = vtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", keyspaceName, "--durability-policy=semi_sync") if err != nil { return 1, err @@ -232,7 +231,6 @@ func TestMain(m *testing.M) { } func TestAlias(t *testing.T) { - defer cluster.PanicHandler(t) insertInitialValues(t) defer deleteInitialValues(t) @@ -296,7 +294,6 @@ func TestAlias(t *testing.T) { } func TestAddAliasWhileVtgateUp(t *testing.T) { - defer cluster.PanicHandler(t) insertInitialValues(t) defer deleteInitialValues(t) diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index b89e007b4f2..ed61f7fd0c9 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -101,9 +101,7 @@ type LocalProcessCluster struct { VtctlMajorVersion int // standalone executable - VtctlclientProcess VtctlClientProcess VtctldClientProcess VtctldClientProcess - VtctlProcess VtctlProcess VtadminProcess VtAdminProcess // background executable processes @@ -249,15 +247,6 @@ func (cluster *LocalProcessCluster) StartTopo() (err error) { } } - cluster.VtctlProcess = *VtctlProcessInstance(cluster.TopoProcess.Port, cluster.Hostname) - if !cluster.ReusingVTDATAROOT { - if err = cluster.VtctlProcess.AddCellInfo(cluster.Cell); err != nil { - log.Error(err) - return - } - cluster.VtctlProcess.LogDir = cluster.TmpDirectory - } - cluster.VtctldProcess = *VtctldProcessInstance(cluster.GetAndReservePort(), cluster.GetAndReservePort(), cluster.TopoProcess.Port, cluster.Hostname, cluster.TmpDirectory) log.Infof("Starting vtctld server on port: %d", cluster.VtctldProcess.Port) @@ -267,8 +256,15 @@ func (cluster *LocalProcessCluster) StartTopo() (err error) { return } - cluster.VtctlclientProcess = *VtctlClientProcessInstance("localhost", cluster.VtctldProcess.GrpcPort, cluster.TmpDirectory) - cluster.VtctldClientProcess = *VtctldClientProcessInstance("localhost", cluster.VtctldProcess.GrpcPort, cluster.TmpDirectory) + cluster.VtctldClientProcess = *cluster.NewVtctldClientProcessInstance("localhost", cluster.VtctldProcess.GrpcPort, cluster.TmpDirectory) + if !cluster.ReusingVTDATAROOT { + if err = cluster.VtctldClientProcess.AddCellInfo(cluster.Cell); err != nil { + log.Error(err) + return + } + cluster.VtctldClientProcess.LogDir = cluster.TmpDirectory + } + return } @@ -388,7 +384,7 @@ func (cluster *LocalProcessCluster) startKeyspace(keyspace Keyspace, shardNames keyspace.SidecarDBName = sidecar.DefaultName } // Create the keyspace if it doesn't already exist. - _ = cluster.VtctlProcess.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName, keyspace.DurabilityPolicy) + _ = cluster.VtctldClientProcess.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName, keyspace.DurabilityPolicy) for _, shardName := range shardNames { shard, err := cluster.AddShard(keyspace.Name, shardName, totalTabletsRequired, rdonly, customizers) if err != nil { @@ -560,7 +556,7 @@ func (cluster *LocalProcessCluster) StartKeyspaceLegacy(keyspace Keyspace, shard keyspace.SidecarDBName = sidecar.DefaultName } // Create the keyspace if it doesn't already exist. - _ = cluster.VtctlProcess.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName, keyspace.DurabilityPolicy) + _ = cluster.VtctldClientProcess.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName, keyspace.DurabilityPolicy) var mysqlctlProcessList []*exec.Cmd for _, shardName := range shardNames { shard := &Shard{ @@ -703,7 +699,7 @@ func (cluster *LocalProcessCluster) SetupCluster(keyspace *Keyspace, shards []Sh if !cluster.ReusingVTDATAROOT { // Create Keyspace - err = cluster.VtctlProcess.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName, keyspace.DurabilityPolicy) + err = cluster.VtctldClientProcess.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName, keyspace.DurabilityPolicy) if err != nil { log.Error(err) return @@ -1043,7 +1039,6 @@ func (cluster *LocalProcessCluster) StreamTabletHealthUntil(ctx context.Context, // Teardown brings down the cluster by invoking teardown for individual processes func (cluster *LocalProcessCluster) Teardown() { - PanicHandler(nil) cluster.mx.Lock() defer cluster.mx.Unlock() if cluster.teardownCompleted { @@ -1295,14 +1290,32 @@ func (cluster *LocalProcessCluster) NewVttabletInstance(tabletType string, UID i // NewVTOrcProcess creates a new VTOrcProcess object func (cluster *LocalProcessCluster) NewVTOrcProcess(config VTOrcConfiguration) *VTOrcProcess { - base := VtctlProcessInstance(cluster.TopoProcess.Port, cluster.Hostname) - base.Binary = "vtorc" + base := VtProcessInstance("vtorc", "vtorc", cluster.TopoProcess.Port, cluster.Hostname) return &VTOrcProcess{ - VtctlProcess: *base, - LogDir: cluster.TmpDirectory, - Config: config, - Port: cluster.GetAndReservePort(), + VtProcess: base, + LogDir: cluster.TmpDirectory, + Config: config, + Port: cluster.GetAndReservePort(), + } +} + +// VtctldClientProcessInstance returns a VtctldProcess handle for a +// vtctldclient process configured with the given Config. +func (cluster *LocalProcessCluster) NewVtctldClientProcessInstance(hostname string, grpcPort int, tmpDirectory string) *VtctldClientProcess { + version, err := GetMajorVersion("vtctldclient") + if err != nil { + log.Warningf("failed to get major vtctldclient version; interop with CLI changes for VEP-4 may not work: %v", err) + } + + base := VtProcessInstance("vtctldclient", "vtctldclient", cluster.TopoProcess.Port, cluster.Hostname) + + vtctldclient := &VtctldClientProcess{ + VtProcess: base, + Server: fmt.Sprintf("%s:%d", hostname, grpcPort), + TempDirectory: tmpDirectory, + VtctldClientMajorVersion: version, } + return vtctldclient } // NewVTAdminProcess creates a new VTAdminProcess object diff --git a/go/test/endtoend/cluster/cluster_util.go b/go/test/endtoend/cluster/cluster_util.go index 061e632dde7..18f78dcb3d0 100644 --- a/go/test/endtoend/cluster/cluster_util.go +++ b/go/test/endtoend/cluster/cluster_util.go @@ -126,15 +126,6 @@ func VerifyRowsInTablet(t *testing.T, vttablet *Vttablet, ksName string, expecte VerifyRowsInTabletForTable(t, vttablet, ksName, expectedRows, "vt_insert_test") } -// PanicHandler handles the panic in the testcase. -func PanicHandler(t testing.TB) { - err := recover() - if t == nil { - return - } - require.Nilf(t, err, "panic occured in testcase %v", t.Name()) -} - // ListBackups Lists back preset in shard func (cluster LocalProcessCluster) ListBackups(shardKsName string) ([]string, error) { output, err := cluster.VtctldClientProcess.ExecuteCommandWithOutput("GetBackups", shardKsName) @@ -308,22 +299,6 @@ func NewConnParams(port int, password, socketPath, keyspace string) mysql.ConnPa } -func filterDoubleDashArgs(args []string, version int) (filtered []string) { - if version > 13 { - return args - } - - for _, arg := range args { - if arg == "--" { - continue - } - - filtered = append(filtered, arg) - } - - return filtered -} - // WriteDbCredentialToTmp writes JSON formatted db credentials to the // specified tmp directory. func WriteDbCredentialToTmp(tmpDir string) string { @@ -389,11 +364,11 @@ func ExecuteOnTablet(t *testing.T, query string, vttablet Vttablet, ks string, e _, _ = vttablet.VttabletProcess.QueryTablet("commit", ks, true) } -func WaitForTabletSetup(vtctlClientProcess *VtctlClientProcess, expectedTablets int, expectedStatus []string) error { +func WaitForTabletSetup(vtctldClientProcess *VtctldClientProcess, expectedTablets int, expectedStatus []string) error { // wait for both tablet to get into replica state in topo waitUntil := time.Now().Add(10 * time.Second) for time.Now().Before(waitUntil) { - result, err := vtctlClientProcess.ExecuteCommandWithOutput("ListAllTablets") + result, err := vtctldClientProcess.ExecuteCommandWithOutput("GetTablets") if err != nil { return err } diff --git a/go/test/endtoend/cluster/vt_process.go b/go/test/endtoend/cluster/vt_process.go new file mode 100644 index 00000000000..d1b7180b31d --- /dev/null +++ b/go/test/endtoend/cluster/vt_process.go @@ -0,0 +1,62 @@ +/* +Copyright 2025 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 cluster + +import ( + "fmt" +) + +// VtProcess is a structure for holding generic vitess process info. +type VtProcess struct { + Name string + Binary string + LogDir string + TopoImplementation string + TopoGlobalAddress string + TopoGlobalRoot string + TopoServerAddress string + TopoRootPath string +} + +// VtProcessInstance returns a VtProcess handle configured with the given Config. +// The process must be manually started by calling setup() +func VtProcessInstance(name, binary string, topoPort int, hostname string) VtProcess { + // Default values for etcd2 topo server. + topoImplementation := "etcd2" + topoRootPath := "/" + + // Checking and resetting the parameters for required topo server. + switch *topoFlavor { + case "zk2": + topoImplementation = "zk2" + case "consul": + topoImplementation = "consul" + // For consul we do not need "/" in the path + topoRootPath = "" + } + + vt := VtProcess{ + Name: name, + Binary: binary, + TopoImplementation: topoImplementation, + TopoGlobalAddress: fmt.Sprintf("%s:%d", hostname, topoPort), + TopoGlobalRoot: TopoGlobalRoot(*topoFlavor), + TopoServerAddress: fmt.Sprintf("%s:%d", hostname, topoPort), + TopoRootPath: topoRootPath, + } + return vt +} diff --git a/go/test/endtoend/cluster/vtbackup_process.go b/go/test/endtoend/cluster/vtbackup_process.go index 57350922a21..ea12c8200d4 100644 --- a/go/test/endtoend/cluster/vtbackup_process.go +++ b/go/test/endtoend/cluster/vtbackup_process.go @@ -31,13 +31,14 @@ import ( // VtbackupProcess is a generic handle for a running Vtbackup. // It can be spawned manually type VtbackupProcess struct { - Name string - Binary string - CommonArg VtctlProcess + VtProcess LogDir string MysqlPort int Directory string + BackupStorageImplementation string + FileBackupStorageRoot string + Cell string Keyspace string Shard string @@ -56,9 +57,9 @@ type VtbackupProcess struct { func (vtbackup *VtbackupProcess) Setup() (err error) { vtbackup.proc = exec.Command( vtbackup.Binary, - "--topo_implementation", vtbackup.CommonArg.TopoImplementation, - "--topo_global_server_address", vtbackup.CommonArg.TopoGlobalAddress, - "--topo_global_root", vtbackup.CommonArg.TopoGlobalRoot, + "--topo_implementation", vtbackup.TopoImplementation, + "--topo_global_server_address", vtbackup.TopoGlobalAddress, + "--topo_global_root", vtbackup.TopoGlobalRoot, "--log_dir", vtbackup.LogDir, //initDBfile is required to run vtbackup @@ -68,8 +69,8 @@ func (vtbackup *VtbackupProcess) Setup() (err error) { "--init_shard", vtbackup.Shard, //Backup Arguments are not optional - "--backup_storage_implementation", "file", - "--file_backup_storage_root", path.Join(os.Getenv("VTDATAROOT"), "tmp", "backupstorage"), + "--backup_storage_implementation", vtbackup.BackupStorageImplementation, + "--file_backup_storage_root", vtbackup.FileBackupStorageRoot, ) if vtbackup.initialBackup { @@ -129,20 +130,20 @@ func (vtbackup *VtbackupProcess) TearDown() error { // The process must be manually started by calling Setup() func VtbackupProcessInstance(tabletUID int, mysqlPort int, newInitDBFile string, keyspace string, shard string, cell string, hostname string, tmpDirectory string, topoPort int, initialBackup bool) *VtbackupProcess { - vtctl := VtctlProcessInstance(topoPort, hostname) + base := VtProcessInstance("vtbackup", "vtbackup", topoPort, hostname) vtbackup := &VtbackupProcess{ - Name: "vtbackup", - Binary: "vtbackup", - CommonArg: *vtctl, - LogDir: tmpDirectory, - Directory: os.Getenv("VTDATAROOT"), - TabletAlias: fmt.Sprintf("%s-%010d", cell, tabletUID), - initDBfile: newInitDBFile, - Keyspace: keyspace, - Shard: shard, - Cell: cell, - MysqlPort: mysqlPort, - initialBackup: initialBackup, + VtProcess: base, + LogDir: tmpDirectory, + Directory: os.Getenv("VTDATAROOT"), + BackupStorageImplementation: "file", + FileBackupStorageRoot: path.Join(os.Getenv("VTDATAROOT"), "/backups"), + TabletAlias: fmt.Sprintf("%s-%010d", cell, tabletUID), + initDBfile: newInitDBFile, + Keyspace: keyspace, + Shard: shard, + Cell: cell, + MysqlPort: mysqlPort, + initialBackup: initialBackup, } return vtbackup } diff --git a/go/test/endtoend/cluster/vtctl_process.go b/go/test/endtoend/cluster/vtctl_process.go deleted file mode 100644 index 185c3079d34..00000000000 --- a/go/test/endtoend/cluster/vtctl_process.go +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright 2019 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 cluster - -import ( - "fmt" - "os/exec" - "strings" - - "vitess.io/vitess/go/vt/log" -) - -// VtctlProcess is a generic handle for a running vtctl command . -// It can be spawned manually -type VtctlProcess struct { - Name string - Binary string - LogDir string - TopoImplementation string - TopoGlobalAddress string - TopoGlobalRoot string - TopoServerAddress string - TopoRootPath string - VtctlMajorVersion int -} - -// AddCellInfo executes vtctl command to add cell info -func (vtctl *VtctlProcess) AddCellInfo(Cell string) (err error) { - tmpProcess := exec.Command( - vtctl.Binary, - "--topo_implementation", vtctl.TopoImplementation, - "--topo_global_server_address", vtctl.TopoGlobalAddress, - "--topo_global_root", vtctl.TopoGlobalRoot, - ) - if *isCoverage { - tmpProcess.Args = append(tmpProcess.Args, "--test.coverprofile="+getCoveragePath("vtctl-addcell.out")) - } - tmpProcess.Args = append(tmpProcess.Args, - "AddCellInfo", "--", - "--root", vtctl.TopoRootPath+Cell, - "--server_address", vtctl.TopoServerAddress, - Cell) - tmpProcess.Args = filterDoubleDashArgs(tmpProcess.Args, vtctl.VtctlMajorVersion) - log.Infof("Adding CellInfo for cell %v with command: %v", Cell, strings.Join(tmpProcess.Args, " ")) - return tmpProcess.Run() -} - -// CreateKeyspace executes vtctl command to create keyspace -func (vtctl *VtctlProcess) CreateKeyspace(keyspace, sidecarDBName, durabilityPolicy string) error { - args := []string{ - "CreateKeyspace", keyspace, - "--sidecar-db-name", sidecarDBName, - } - if durabilityPolicy != "" { - args = append(args, "--durability-policy", durabilityPolicy) - } - output, err := vtctl.ExecuteCommandWithOutput(args...) - if err != nil { - log.Errorf("CreateKeyspace returned err: %s, output: %s", err, output) - } - return err -} - -// ExecuteCommandWithOutput executes any vtctlclient command and returns output -func (vtctl *VtctlProcess) ExecuteCommandWithOutput(args ...string) (result string, err error) { - args = append([]string{ - "--log_dir", vtctl.LogDir, - "--topo_implementation", vtctl.TopoImplementation, - "--topo_global_server_address", vtctl.TopoGlobalAddress, - "--topo_global_root", vtctl.TopoGlobalRoot}, args...) - if *isCoverage { - args = append([]string{"--test.coverprofile=" + getCoveragePath("vtctl-o-"+args[0]+".out"), "--test.v"}, args...) - } - tmpProcess := exec.Command( - vtctl.Binary, - filterDoubleDashArgs(args, vtctl.VtctlMajorVersion)..., - ) - log.Info(fmt.Sprintf("Executing vtctlclient with arguments %v", strings.Join(tmpProcess.Args, " "))) - resultByte, err := tmpProcess.CombinedOutput() - return filterResultForWarning(filterResultWhenRunsForCoverage(string(resultByte))), err -} - -// ExecuteCommand executes any vtctlclient command -func (vtctl *VtctlProcess) ExecuteCommand(args ...string) (err error) { - args = append([]string{ - "--topo_implementation", vtctl.TopoImplementation, - "--topo_global_server_address", vtctl.TopoGlobalAddress, - "--topo_global_root", vtctl.TopoGlobalRoot}, args...) - if *isCoverage { - args = append([]string{"--test.coverprofile=" + getCoveragePath("vtctl-"+args[0]+".out"), "--test.v"}, args...) - } - tmpProcess := exec.Command( - vtctl.Binary, - filterDoubleDashArgs(args, vtctl.VtctlMajorVersion)..., - ) - log.Info(fmt.Sprintf("Executing vtctlclient with arguments %v", strings.Join(tmpProcess.Args, " "))) - return tmpProcess.Run() -} - -// VtctlProcessInstance returns a VtctlProcess handle for vtctl process -// configured with the given Config. -// The process must be manually started by calling setup() -func VtctlProcessInstance(topoPort int, hostname string) *VtctlProcess { - - // Default values for etcd2 topo server. - topoImplementation := "etcd2" - topoRootPath := "/" - - // Checking and resetting the parameters for required topo server. - switch *topoFlavor { - case "zk2": - topoImplementation = "zk2" - case "consul": - topoImplementation = "consul" - // For consul we do not need "/" in the path - topoRootPath = "" - } - - version, err := GetMajorVersion("vtctl") - if err != nil { - log.Warningf("failed to get major vtctl version; interop with CLI changes for VEP-4 may not work: %s", err) - } - - vtctl := &VtctlProcess{ - Name: "vtctl", - Binary: "vtctl", - TopoImplementation: topoImplementation, - TopoGlobalAddress: fmt.Sprintf("%s:%d", hostname, topoPort), - TopoGlobalRoot: TopoGlobalRoot(*topoFlavor), - TopoServerAddress: fmt.Sprintf("%s:%d", hostname, topoPort), - TopoRootPath: topoRootPath, - VtctlMajorVersion: version, - } - return vtctl -} diff --git a/go/test/endtoend/cluster/vtctlclient_process.go b/go/test/endtoend/cluster/vtctlclient_process.go deleted file mode 100644 index 0c5fb1bc8c2..00000000000 --- a/go/test/endtoend/cluster/vtctlclient_process.go +++ /dev/null @@ -1,266 +0,0 @@ -/* -Copyright 2019 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 cluster - -import ( - "fmt" - "os/exec" - "strings" - "time" - - "vitess.io/vitess/go/vt/vterrors" - - "vitess.io/vitess/go/vt/log" -) - -// VtctlClientProcess is a generic handle for a running vtctlclient command . -// It can be spawned manually -type VtctlClientProcess struct { - Name string - Binary string - Server string - TempDirectory string - ZoneName string - VtctlClientMajorVersion int -} - -// VtctlClientParams encapsulated params to provide if non-default -type VtctlClientParams struct { - DDLStrategy string - MigrationContext string - UUIDList string - CallerID string - BatchSize int -} - -// InitShardPrimary executes vtctlclient command to make specified tablet the primary for the shard. -func (vtctlclient *VtctlClientProcess) InitShardPrimary(Keyspace string, Shard string, Cell string, TabletUID int) (err error) { - output, err := vtctlclient.ExecuteCommandWithOutput( - "InitShardPrimary", "--", - "--force", "--wait_replicas_timeout", "31s", - fmt.Sprintf("%s/%s", Keyspace, Shard), - fmt.Sprintf("%s-%d", Cell, TabletUID)) - if err != nil { - log.Errorf("error in InitShardPrimary output %s, err %s", output, err.Error()) - } - return err -} - -// InitializeShard executes vtctlclient command to make specified tablet the primary for the shard. -func (vtctlclient *VtctlClientProcess) InitializeShard(Keyspace string, Shard string, Cell string, TabletUID int) (err error) { - output, err := vtctlclient.ExecuteCommandWithOutput( - "PlannedReparentShard", "--", - "--keyspace_shard", fmt.Sprintf("%s/%s", Keyspace, Shard), - "--wait_replicas_timeout", "31s", - "--new_primary", fmt.Sprintf("%s-%d", Cell, TabletUID)) - if err != nil { - log.Errorf("error in PlannedReparentShard output %s, err %s", output, err.Error()) - } - return err -} - -// ApplySchemaWithOutput applies SQL schema to the keyspace -func (vtctlclient *VtctlClientProcess) ApplySchemaWithOutput(Keyspace string, SQL string, params VtctlClientParams) (result string, err error) { - args := []string{ - "ApplySchema", "--", - "--sql", SQL, - } - if params.MigrationContext != "" { - args = append(args, "--migration_context", params.MigrationContext) - } - if params.DDLStrategy != "" { - args = append(args, "--ddl_strategy", params.DDLStrategy) - } - if params.UUIDList != "" { - args = append(args, "--uuid_list", params.UUIDList) - } - if params.BatchSize > 0 { - args = append(args, "--batch_size", fmt.Sprintf("%d", params.BatchSize)) - } - if params.CallerID != "" { - args = append(args, "--caller_id", params.CallerID) - } - args = append(args, Keyspace) - return vtctlclient.ExecuteCommandWithOutput(args...) -} - -// ApplySchema applies SQL schema to the keyspace -func (vtctlclient *VtctlClientProcess) ApplySchema(Keyspace string, SQL string) error { - message, err := vtctlclient.ApplySchemaWithOutput(Keyspace, SQL, VtctlClientParams{DDLStrategy: "direct -allow-zero-in-date"}) - - return vterrors.Wrap(err, message) -} - -// ApplyVSchema applies vitess schema (JSON format) to the keyspace -func (vtctlclient *VtctlClientProcess) ApplyVSchema(Keyspace string, JSON string) (err error) { - return vtctlclient.ExecuteCommand( - "ApplyVSchema", "--", - "--vschema", JSON, - Keyspace, - ) -} - -// ApplyRoutingRules does it -func (vtctlclient *VtctlClientProcess) ApplyRoutingRules(JSON string) (err error) { - return vtctlclient.ExecuteCommand("ApplyRoutingRules", "--", "--rules", JSON) -} - -// ApplyRoutingRules does it -func (vtctlclient *VtctlClientProcess) ApplyShardRoutingRules(JSON string) (err error) { - return vtctlclient.ExecuteCommand("ApplyShardRoutingRules", "--", "--rules", JSON) -} - -// OnlineDDLShowRecent responds with recent schema migration list -func (vtctlclient *VtctlClientProcess) OnlineDDLShowRecent(Keyspace string) (result string, err error) { - return vtctlclient.ExecuteCommandWithOutput( - "OnlineDDL", - Keyspace, - "show", - "recent", - ) -} - -// OnlineDDLCancelMigration cancels a given migration uuid -func (vtctlclient *VtctlClientProcess) OnlineDDLCancelMigration(Keyspace, uuid string) (result string, err error) { - return vtctlclient.ExecuteCommandWithOutput( - "OnlineDDL", - Keyspace, - "cancel", - uuid, - ) -} - -// OnlineDDLCancelAllMigrations cancels all migrations for a keyspace -func (vtctlclient *VtctlClientProcess) OnlineDDLCancelAllMigrations(Keyspace string) (result string, err error) { - return vtctlclient.ExecuteCommandWithOutput( - "OnlineDDL", - Keyspace, - "cancel-all", - ) -} - -// OnlineDDLRetryMigration retries a given migration uuid -func (vtctlclient *VtctlClientProcess) OnlineDDLRetryMigration(Keyspace, uuid string) (result string, err error) { - return vtctlclient.ExecuteCommandWithOutput( - "OnlineDDL", - Keyspace, - "retry", - uuid, - ) -} - -// OnlineDDLRevertMigration reverts a given migration uuid -func (vtctlclient *VtctlClientProcess) OnlineDDLRevertMigration(Keyspace, uuid string) (result string, err error) { - return vtctlclient.ExecuteCommandWithOutput( - "OnlineDDL", - Keyspace, - "revert", - uuid, - ) -} - -// VExec runs a VExec query -func (vtctlclient *VtctlClientProcess) VExec(Keyspace, workflow, query string) (result string, err error) { - return vtctlclient.ExecuteCommandWithOutput( - "VExec", - fmt.Sprintf("%s.%s", Keyspace, workflow), - query, - ) -} - -// ExecuteCommand executes any vtctlclient command -func (vtctlclient *VtctlClientProcess) ExecuteCommand(args ...string) (err error) { - output, err := vtctlclient.ExecuteCommandWithOutput(args...) - if output != "" { - if err != nil { - log.Errorf("Output:\n%v", output) - } - } - return err -} - -// ExecuteCommandWithOutput executes any vtctlclient command and returns output -func (vtctlclient *VtctlClientProcess) ExecuteCommandWithOutput(args ...string) (string, error) { - var resultByte []byte - var resultStr string - var err error - retries := 10 - retryDelay := 1 * time.Second - pArgs := []string{"--server", vtctlclient.Server} - if *isCoverage { - pArgs = append(pArgs, "--test.coverprofile="+getCoveragePath("vtctlclient-"+args[0]+".out"), "--test.v") - } - pArgs = append(pArgs, args...) - for i := 1; i <= retries; i++ { - tmpProcess := exec.Command( - vtctlclient.Binary, - filterDoubleDashArgs(pArgs, vtctlclient.VtctlClientMajorVersion)..., - ) - log.Infof("Executing vtctlclient with command: %v (attempt %d of %d)", strings.Join(tmpProcess.Args, " "), i, retries) - resultByte, err = tmpProcess.CombinedOutput() - resultStr = string(resultByte) - if err == nil || !shouldRetry(resultStr) { - break - } - time.Sleep(retryDelay) - } - return filterResultForWarning(filterResultWhenRunsForCoverage(resultStr)), err -} - -// VtctlClientProcessInstance returns a VtctlProcess handle for vtctlclient process -// configured with the given Config. -func VtctlClientProcessInstance(hostname string, grpcPort int, tmpDirectory string) *VtctlClientProcess { - version, err := GetMajorVersion("vtctl") // `vtctlclient` does not have a --version flag, so we assume both vtctl/vtctlclient have the same version - if err != nil { - log.Warningf("failed to get major vtctlclient version; interop with CLI changes for VEP-4 may not work: %s", err) - } - - vtctlclient := &VtctlClientProcess{ - Name: "vtctlclient", - Binary: "vtctlclient", - Server: fmt.Sprintf("%s:%d", hostname, grpcPort), - TempDirectory: tmpDirectory, - VtctlClientMajorVersion: version, - } - return vtctlclient -} - -// InitTablet initializes a tablet -func (vtctlclient *VtctlClientProcess) InitTablet(tablet *Vttablet, cell string, keyspaceName string, hostname string, shardName string) error { - tabletType := "replica" - if tablet.Type == "rdonly" { - tabletType = "rdonly" - } - args := []string{"InitTablet", "--", "--hostname", hostname, - "--port", fmt.Sprintf("%d", tablet.HTTPPort), "--allow_update", "--parent", - "--keyspace", keyspaceName, - "--shard", shardName} - if tablet.MySQLPort > 0 { - args = append(args, "--mysql_port", fmt.Sprintf("%d", tablet.MySQLPort)) - } - if tablet.GrpcPort > 0 { - args = append(args, "--grpc_port", fmt.Sprintf("%d", tablet.GrpcPort)) - } - args = append(args, fmt.Sprintf("%s-%010d", cell, tablet.TabletUID), tabletType) - return vtctlclient.ExecuteCommand(args...) -} - -// shouldRetry tells us if the command should be retried based on the results/output -- meaning that it -// is likely an ephemeral or recoverable issue that is likely to succeed when retried. -func shouldRetry(cmdResults string) bool { - return strings.Contains(cmdResults, "Deadlock found when trying to get lock; try restarting transaction") -} diff --git a/go/test/endtoend/cluster/vtctld_process.go b/go/test/endtoend/cluster/vtctld_process.go index 6ac6ed5d2b0..831f5a23af7 100644 --- a/go/test/endtoend/cluster/vtctld_process.go +++ b/go/test/endtoend/cluster/vtctld_process.go @@ -32,9 +32,7 @@ import ( // VtctldProcess is a generic handle for a running vtctld . // It can be spawned manually type VtctldProcess struct { - Name string - Binary string - CommonArg VtctlProcess + VtProcess ServiceMap string BackupStorageImplementation string FileBackupStorageRoot string @@ -55,9 +53,9 @@ func (vtctld *VtctldProcess) Setup(cell string, extraArgs ...string) (err error) _ = createDirectory(path.Join(vtctld.Directory, "backups"), 0700) vtctld.proc = exec.Command( vtctld.Binary, - "--topo_implementation", vtctld.CommonArg.TopoImplementation, - "--topo_global_server_address", vtctld.CommonArg.TopoGlobalAddress, - "--topo_global_root", vtctld.CommonArg.TopoGlobalRoot, + "--topo_implementation", vtctld.TopoImplementation, + "--topo_global_server_address", vtctld.TopoGlobalAddress, + "--topo_global_root", vtctld.TopoGlobalRoot, "--cell", cell, "--service_map", vtctld.ServiceMap, "--backup_storage_implementation", vtctld.BackupStorageImplementation, @@ -164,15 +162,13 @@ func (vtctld *VtctldProcess) TearDown() error { } } -// VtctldProcessInstance returns a VtctlProcess handle for vtctl process +// VtctldProcessInstance returns a VtctldProcess handle // configured with the given Config. // The process must be manually started by calling setup() func VtctldProcessInstance(httpPort int, grpcPort int, topoPort int, hostname string, tmpDirectory string) *VtctldProcess { - vtctl := VtctlProcessInstance(topoPort, hostname) + base := VtProcessInstance("vtctld", "vtctld", topoPort, hostname) vtctld := &VtctldProcess{ - Name: "vtctld", - Binary: "vtctld", - CommonArg: *vtctl, + VtProcess: base, ServiceMap: "grpc-vtctl,grpc-vtctld", BackupStorageImplementation: "file", FileBackupStorageRoot: path.Join(os.Getenv("VTDATAROOT"), "/backups"), diff --git a/go/test/endtoend/cluster/vtctldclient_process.go b/go/test/endtoend/cluster/vtctldclient_process.go index 8b401f59070..3dc1a811930 100644 --- a/go/test/endtoend/cluster/vtctldclient_process.go +++ b/go/test/endtoend/cluster/vtctldclient_process.go @@ -19,6 +19,7 @@ package cluster import ( "fmt" "os/exec" + "slices" "strings" "time" @@ -35,8 +36,7 @@ import ( // VtctldClientProcess is a generic handle for a running vtctldclient command . // It can be spawned manually type VtctldClientProcess struct { - Name string - Binary string + VtProcess Server string TempDirectory string ZoneName string @@ -44,6 +44,25 @@ type VtctldClientProcess struct { Quiet bool } +// VtctldClientProcessInstance returns a VtctldClientProcess handle +// configured with the given Config. +// The process must be manually started by calling setup() +func VtctldClientProcessInstance(grpcPort int, topoPort int, hostname string, tmpDirectory string) *VtctldClientProcess { + version, err := GetMajorVersion("vtctld") // `vtctldclient` does not have a --version flag, so we assume both vtctl/vtctldclient have the same version + if err != nil { + log.Warningf("failed to get major vtctldclient version; interop with CLI changes for VEP-4 may not work: %s", err) + } + + base := VtProcessInstance("vtctldclient", "vtctldclient", topoPort, hostname) + vtctldclient := &VtctldClientProcess{ + VtProcess: base, + Server: fmt.Sprintf("%s:%d", hostname, grpcPort), + TempDirectory: tmpDirectory, + VtctldClientMajorVersion: version, + } + return vtctldclient +} + // ExecuteCommand executes any vtctldclient command func (vtctldclient *VtctldClientProcess) ExecuteCommand(args ...string) (err error) { output, err := vtctldclient.ExecuteCommandWithOutput(args...) @@ -55,14 +74,24 @@ func (vtctldclient *VtctldClientProcess) ExecuteCommand(args ...string) (err err return err } -// ExecuteCommandWithOutput executes any vtctldclient command and returns output +// ExecuteCommandWithOutput executes any vtctldclient command and returns output. func (vtctldclient *VtctldClientProcess) ExecuteCommandWithOutput(args ...string) (string, error) { var resultByte []byte var resultStr string var err error retries := 10 retryDelay := 1 * time.Second - pArgs := []string{"--server", vtctldclient.Server} + pArgs := []string{ + // These are needed to support --server=internal and are otherwise + // ignored/unused. + "--topo-implementation", vtctldclient.TopoImplementation, + "--topo-global-server-address", vtctldclient.TopoGlobalAddress, + "--topo-global-root", vtctldclient.TopoGlobalRoot, + } + if !slices.Contains(args, "--server") { + // Only add the default server if one was not already specified. + pArgs = append(pArgs, "--server", vtctldclient.Server) + } if *isCoverage { pArgs = append(pArgs, "--test.coverprofile="+getCoveragePath("vtctldclient-"+args[0]+".out"), "--test.v") } @@ -70,7 +99,7 @@ func (vtctldclient *VtctldClientProcess) ExecuteCommandWithOutput(args ...string for i := range retries { tmpProcess := exec.Command( vtctldclient.Binary, - filterDoubleDashArgs(pArgs, vtctldclient.VtctldClientMajorVersion)..., + pArgs..., ) msg := binlogplayer.LimitString(strings.Join(tmpProcess.Args, " "), 256) // limit log line length if !vtctldclient.Quiet { @@ -86,22 +115,19 @@ func (vtctldclient *VtctldClientProcess) ExecuteCommandWithOutput(args ...string return filterResultWhenRunsForCoverage(resultStr), err } -// VtctldClientProcessInstance returns a VtctldProcess handle for vtctldclient process -// configured with the given Config. -func VtctldClientProcessInstance(hostname string, grpcPort int, tmpDirectory string) *VtctldClientProcess { - version, err := GetMajorVersion("vtctld") // `vtctldclient` does not have a --version flag, so we assume both vtctl/vtctldclient have the same version - if err != nil { - log.Warningf("failed to get major vtctldclient version; interop with CLI changes for VEP-4 may not work: %s", err) - } - - vtctldclient := &VtctldClientProcess{ - Name: "vtctldclient", - Binary: "vtctldclient", - Server: fmt.Sprintf("%s:%d", hostname, grpcPort), - TempDirectory: tmpDirectory, - VtctldClientMajorVersion: version, +// AddCellInfo executes the vtctldclient command to add cell info. +// It uses --server=internal as there may not yet be a vtctld running +// as we need to create a cell for vtctld to use first. +func (vtctldclient *VtctldClientProcess) AddCellInfo(Cell string) error { + args := []string{ + "--server", "internal", + "AddCellInfo", + "--root", vtctldclient.TopoRootPath + Cell, + "--server-address", vtctldclient.TopoServerAddress, + Cell, } - return vtctldclient + _, err := vtctldclient.ExecuteCommandWithOutput(args...) + return err } // ApplyRoutingRules applies the given routing rules. @@ -233,16 +259,17 @@ func (vtctldclient *VtctldClientProcess) InitShardPrimary(keyspace string, shard return err } -// CreateKeyspace executes the vtctl command to create a keyspace -func (vtctldclient *VtctldClientProcess) CreateKeyspace(keyspaceName string, sidecarDBName string) (err error) { +// CreateKeyspace executes the vtctldclient command to create a keyspace +func (vtctldclient *VtctldClientProcess) CreateKeyspace(keyspaceName string, sidecarDBName string, durabilityPolicy string) (err error) { var output string - // For upgrade/downgrade tests where an older version is also used. - if vtctldclient.VtctldClientMajorVersion < 17 { - log.Errorf("CreateKeyspace does not support the --sidecar-db-name flag in vtctl version %d; ignoring...", vtctldclient.VtctldClientMajorVersion) - output, err = vtctldclient.ExecuteCommandWithOutput("CreateKeyspace", keyspaceName) - } else { - output, err = vtctldclient.ExecuteCommandWithOutput("CreateKeyspace", keyspaceName, "--sidecar-db-name", sidecarDBName) + args := []string{ + "CreateKeyspace", keyspaceName, + "--sidecar-db-name", sidecarDBName, + } + if durabilityPolicy != "" { + args = append(args, "--durability-policy", durabilityPolicy) } + output, err = vtctldclient.ExecuteCommandWithOutput(args...) if err != nil { log.Errorf("CreateKeyspace returned err: %s, output: %s", err, output) } @@ -314,3 +341,10 @@ func (vtctldclient *VtctldClientProcess) OnlineDDLShow(keyspace, workflow string workflow, ) } + +// shouldRetry tells us if the command should be retried based on the results/output +// -- meaning that it is likely an ephemeral or recoverable issue that is likely to +// succeed when retried. +func shouldRetry(cmdResults string) bool { + return strings.Contains(cmdResults, "Deadlock found when trying to get lock; try restarting transaction") +} diff --git a/go/test/endtoend/cluster/vtgate_process.go b/go/test/endtoend/cluster/vtgate_process.go index c01f7c6e93b..53b8b6152e8 100644 --- a/go/test/endtoend/cluster/vtgate_process.go +++ b/go/test/endtoend/cluster/vtgate_process.go @@ -28,6 +28,7 @@ import ( "strconv" "strings" "syscall" + "testing" "time" "vitess.io/vitess/go/vt/log" @@ -39,9 +40,7 @@ import ( // VtgateProcess is a generic handle for a running vtgate . // It can be spawned manually type VtgateProcess struct { - Name string - Binary string - CommonArg VtctlProcess + VtProcess LogDir string ErrorLog string FileToLogQueries string @@ -57,6 +56,8 @@ type VtgateProcess struct { Directory string VerifyURL string VSchemaURL string + ConfigFile string + Config VTGateConfiguration SysVarSetEnabled bool PlannerVersion plancontext.PlannerVersion // Extra Args to be set before starting the vtgate process @@ -66,14 +67,90 @@ type VtgateProcess struct { exit chan error } +type VTGateConfiguration struct { + TransactionMode string `json:"transaction_mode,omitempty"` + DiscoveryLowReplicationLag string `json:"discovery_low_replication_lag,omitempty"` + DiscoveryHighReplicationLag string `json:"discovery_high_replication_lag,omitempty"` + DiscoveryMinServingVttablets string `json:"discovery_min_number_serving_vttablets,omitempty"` + DiscoveryLegacyReplicationLagAlgo string `json:"discovery_legacy_replication_lag_algorithm"` +} + +// ToJSONString will marshal this configuration as JSON +func (config *VTGateConfiguration) ToJSONString() string { + b, _ := json.MarshalIndent(config, "", "\t") + return string(b) +} + +func (vtgate *VtgateProcess) RewriteConfiguration() error { + return os.WriteFile(vtgate.ConfigFile, []byte(vtgate.Config.ToJSONString()), 0644) +} + +// WaitForConfig waits for the expectedConfig to be present in the vtgate configuration. +func (vtgate *VtgateProcess) WaitForConfig(expectedConfig string) error { + timeout := time.After(30 * time.Second) + var response string + for { + select { + case <-timeout: + return fmt.Errorf("timed out waiting for api to work. Last response - %s", response) + default: + _, response, _ = vtgate.MakeAPICall("/debug/config") + if strings.Contains(response, expectedConfig) { + return nil + } + time.Sleep(1 * time.Second) + } + } +} + +// MakeAPICall makes an API call on the given endpoint of VTOrc +func (vtgate *VtgateProcess) MakeAPICall(endpoint string) (status int, response string, err error) { + url := fmt.Sprintf("http://localhost:%d/%s", vtgate.Port, endpoint) + resp, err := http.Get(url) + if err != nil { + if resp != nil { + status = resp.StatusCode + } + return status, "", err + } + defer func() { + if resp != nil && resp.Body != nil { + resp.Body.Close() + } + }() + + respByte, _ := io.ReadAll(resp.Body) + return resp.StatusCode, string(respByte), err +} + +// MakeAPICallRetry is used to make an API call and retries until success +func (vtgate *VtgateProcess) MakeAPICallRetry(t *testing.T, url string) { + t.Helper() + timeout := time.After(10 * time.Second) + for { + select { + case <-timeout: + t.Fatal("timed out waiting for api to work") + return + default: + status, _, err := vtgate.MakeAPICall(url) + if err == nil && status == 200 { + return + } + time.Sleep(1 * time.Second) + } + } +} + const defaultVtGatePlannerVersion = planbuilder.Gen4 // Setup starts Vtgate process with required arguements func (vtgate *VtgateProcess) Setup() (err error) { args := []string{ - "--topo_implementation", vtgate.CommonArg.TopoImplementation, - "--topo_global_server_address", vtgate.CommonArg.TopoGlobalAddress, - "--topo_global_root", vtgate.CommonArg.TopoGlobalRoot, + "--topo_implementation", vtgate.TopoImplementation, + "--topo_global_server_address", vtgate.TopoGlobalAddress, + "--topo_global_root", vtgate.TopoGlobalRoot, + "--config-file", vtgate.ConfigFile, "--log_dir", vtgate.LogDir, "--log_queries_to_file", vtgate.FileToLogQueries, "--port", fmt.Sprintf("%d", vtgate.Port), @@ -98,6 +175,19 @@ func (vtgate *VtgateProcess) Setup() (err error) { break } } + configFile, err := os.Create(vtgate.ConfigFile) + if err != nil { + log.Errorf("cannot create config file for vtgate: %v", err) + return err + } + _, err = configFile.WriteString(vtgate.Config.ToJSONString()) + if err != nil { + return err + } + err = configFile.Close() + if err != nil { + return err + } if !msvflag { version, err := mysqlctl.GetVersionString() if err != nil { @@ -132,6 +222,7 @@ func (vtgate *VtgateProcess) Setup() (err error) { return err } vtgate.proc.Stderr = errFile + vtgate.ErrorLog = errFile.Name() vtgate.proc.Env = append(vtgate.proc.Env, os.Environ()...) vtgate.proc.Env = append(vtgate.proc.Env, DefaultVttestEnv) @@ -281,11 +372,11 @@ func VtgateProcessInstance( extraArgs []string, plannerVersion plancontext.PlannerVersion, ) *VtgateProcess { - vtctl := VtctlProcessInstance(topoPort, hostname) + base := VtProcessInstance("vtgate", "vtgate", topoPort, hostname) vtgate := &VtgateProcess{ - Name: "vtgate", - Binary: "vtgate", + VtProcess: base, FileToLogQueries: path.Join(tmpDirectory, "/vtgate_querylog.txt"), + ConfigFile: path.Join(tmpDirectory, fmt.Sprintf("vtgate-config-%d.json", port)), Directory: os.Getenv("VTDATAROOT"), ServiceMap: "grpc-tabletmanager,grpc-throttler,grpc-queryservice,grpc-updatestream,grpc-vtctl,grpc-vtgateservice", LogDir: tmpDirectory, @@ -296,7 +387,6 @@ func VtgateProcessInstance( Cell: cell, CellsToWatch: cellsToWatch, TabletTypesToWait: tabletTypesToWait, - CommonArg: *vtctl, MySQLAuthServerImpl: "none", ExtraArgs: extraArgs, PlannerVersion: plannerVersion, diff --git a/go/test/endtoend/cluster/vtorc_process.go b/go/test/endtoend/cluster/vtorc_process.go index af101a8bebd..4d726241756 100644 --- a/go/test/endtoend/cluster/vtorc_process.go +++ b/go/test/endtoend/cluster/vtorc_process.go @@ -36,7 +36,7 @@ import ( // VTOrcProcess is a test struct for running // vtorc as a separate process for testing type VTOrcProcess struct { - VtctlProcess + VtProcess Port int LogDir string LogFileName string @@ -83,7 +83,6 @@ func (orc *VTOrcProcess) RewriteConfiguration() error { // Setup starts orc process with required arguements func (orc *VTOrcProcess) Setup() (err error) { - // create the configuration file timeNow := time.Now().UnixNano() err = os.MkdirAll(orc.LogDir, 0755) diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go index 6bc6e6b8d7f..65c6fbeec26 100644 --- a/go/test/endtoend/cluster/vttablet_process.go +++ b/go/test/endtoend/cluster/vttablet_process.go @@ -47,8 +47,7 @@ const vttabletStateTimeout = 60 * time.Second // VttabletProcess is a generic handle for a running vttablet . // It can be spawned manually type VttabletProcess struct { - Name string - Binary string + VtProcess FileToLogQueries string TabletUID int TabletPath string @@ -56,7 +55,6 @@ type VttabletProcess struct { Port int GrpcPort int Shard string - CommonArg VtctlProcess LogDir string ErrorLog string TabletHostname string @@ -93,9 +91,9 @@ type VttabletProcess struct { func (vttablet *VttabletProcess) Setup() (err error) { vttablet.proc = exec.Command( vttablet.Binary, - "--topo_implementation", vttablet.CommonArg.TopoImplementation, - "--topo_global_server_address", vttablet.CommonArg.TopoGlobalAddress, - "--topo_global_root", vttablet.CommonArg.TopoGlobalRoot, + "--topo_implementation", vttablet.TopoImplementation, + "--topo_global_server_address", vttablet.TopoGlobalAddress, + "--topo_global_root", vttablet.TopoGlobalRoot, "--log_queries_to_file", vttablet.FileToLogQueries, "--tablet-path", vttablet.TabletPath, "--port", fmt.Sprintf("%d", vttablet.Port), @@ -717,10 +715,9 @@ func (vttablet *VttabletProcess) IsShutdown() bool { // configured with the given Config. // The process must be manually started by calling setup() func VttabletProcessInstance(port, grpcPort, tabletUID int, cell, shard, keyspace string, vtctldPort int, tabletType string, topoPort int, hostname, tmpDirectory string, extraArgs []string, charset string) *VttabletProcess { - vtctl := VtctlProcessInstance(topoPort, hostname) + base := VtProcessInstance("vttablet", "vttablet", topoPort, hostname) vttablet := &VttabletProcess{ - Name: "vttablet", - Binary: "vttablet", + VtProcess: base, FileToLogQueries: path.Join(tmpDirectory, fmt.Sprintf("/vt_%010d_querylog.txt", tabletUID)), Directory: path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/vt_%010d", tabletUID)), Cell: cell, @@ -731,7 +728,6 @@ func VttabletProcessInstance(port, grpcPort, tabletUID int, cell, shard, keyspac TabletHostname: hostname, Keyspace: keyspace, TabletType: "replica", - CommonArg: *vtctl, HealthCheckInterval: 5, Port: port, GrpcPort: grpcPort, diff --git a/go/test/endtoend/clustertest/add_keyspace_test.go b/go/test/endtoend/clustertest/add_keyspace_test.go index edee87d035e..b8422b52eb3 100644 --- a/go/test/endtoend/clustertest/add_keyspace_test.go +++ b/go/test/endtoend/clustertest/add_keyspace_test.go @@ -61,7 +61,6 @@ primary key (id) ) func TestAddKeyspace(t *testing.T) { - defer cluster.PanicHandler(t) if err := clusterInstance.StartKeyspace(*testKeyspace, []string{"-80", "80-"}, 0, false); err != nil { log.Errorf("failed to AddKeyspace %v: %v", *testKeyspace, err) t.Fatal(err) diff --git a/go/test/endtoend/clustertest/etcd_test.go b/go/test/endtoend/clustertest/etcd_test.go index 5239d960c47..f47a002a3cf 100644 --- a/go/test/endtoend/clustertest/etcd_test.go +++ b/go/test/endtoend/clustertest/etcd_test.go @@ -24,12 +24,9 @@ import ( "github.com/stretchr/testify/require" clientv3 "go.etcd.io/etcd/client/v3" - - "vitess.io/vitess/go/test/endtoend/cluster" ) func TestEtcdServer(t *testing.T) { - defer cluster.PanicHandler(t) // Confirm the basic etcd cluster health. etcdHealthURL := fmt.Sprintf("http://%s:%d/health", clusterInstance.Hostname, clusterInstance.TopoPort) diff --git a/go/test/endtoend/clustertest/main_test.go b/go/test/endtoend/clustertest/main_test.go index 35da40a3edb..3fc2524208b 100644 --- a/go/test/endtoend/clustertest/main_test.go +++ b/go/test/endtoend/clustertest/main_test.go @@ -60,7 +60,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/clustertest/vtctld_test.go b/go/test/endtoend/clustertest/vtctld_test.go index c61f7820bb7..18d06cf3299 100644 --- a/go/test/endtoend/clustertest/vtctld_test.go +++ b/go/test/endtoend/clustertest/vtctld_test.go @@ -30,8 +30,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/test/endtoend/cluster" ) var ( @@ -44,7 +42,6 @@ var ( ) func TestVtctldProcess(t *testing.T) { - defer cluster.PanicHandler(t) url := fmt.Sprintf("http://%s:%d/api/keyspaces/", clusterInstance.Hostname, clusterInstance.VtctldHTTPPort) testURL(t, url, "keyspace url") diff --git a/go/test/endtoend/clustertest/vtgate_test.go b/go/test/endtoend/clustertest/vtgate_test.go index 2f72682a391..264b292f482 100644 --- a/go/test/endtoend/clustertest/vtgate_test.go +++ b/go/test/endtoend/clustertest/vtgate_test.go @@ -32,11 +32,9 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" ) func TestVtgateProcess(t *testing.T) { - defer cluster.PanicHandler(t) verifyVtgateVariables(t, clusterInstance.VtgateProcess.VerifyURL) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) diff --git a/go/test/endtoend/clustertest/vttablet_test.go b/go/test/endtoend/clustertest/vttablet_test.go index 5e7d5e27182..86fc2a6983c 100644 --- a/go/test/endtoend/clustertest/vttablet_test.go +++ b/go/test/endtoend/clustertest/vttablet_test.go @@ -25,12 +25,9 @@ import ( "testing" "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/test/endtoend/cluster" ) func TestVttabletProcess(t *testing.T) { - defer cluster.PanicHandler(t) firstTabletPort := clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].HTTPPort testURL(t, fmt.Sprintf("http://localhost:%d/debug/vars/", firstTabletPort), "tablet debug var url") resp, err := http.Get(fmt.Sprintf("http://localhost:%d/debug/vars", firstTabletPort)) @@ -48,7 +45,6 @@ func TestVttabletProcess(t *testing.T) { } func TestDeleteTablet(t *testing.T) { - defer cluster.PanicHandler(t) primary := clusterInstance.Keyspaces[0].Shards[0].PrimaryTablet() require.NotNil(t, primary) _, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("DeleteTablets", "--allow-primary", primary.Alias) diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index e34be52accf..4cbe5cdf0fc 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -140,8 +140,8 @@ func TestVtctldCommands(t *testing.T) { err = vtest.waitUntilDockerHealthy(10) require.NoError(t, err) - vtctldClient := cluster.VtctldClientProcessInstance("localhost", vtest.basePort+1, os.TempDir()) - res, err := vtctldClient.ExecuteCommandWithOutput("GetKeyspaces") + vtctldClient := cluster.VtctldClientProcessInstance(vtest.basePort+1, 0, "localhost", os.TempDir()) + res, err := vtctldClient.ExecuteCommandWithOutput("--server", "internal", "GetKeyspaces") require.NoError(t, err) // We verify that the command succeeds, and the keyspace name is present in the output. require.Contains(t, res, "long_ks_name") diff --git a/go/test/endtoend/encryption/encryptedreplication/encrypted_replication_test.go b/go/test/endtoend/encryption/encryptedreplication/encrypted_replication_test.go index 7dea6cf525f..0d47f8fad4d 100644 --- a/go/test/endtoend/encryption/encryptedreplication/encrypted_replication_test.go +++ b/go/test/endtoend/encryption/encryptedreplication/encrypted_replication_test.go @@ -42,7 +42,6 @@ var ( // This test makes sure that we can use SSL replication with Vitess func TestSecure(t *testing.T) { - defer cluster.PanicHandler(t) testReplicationBase(t, true) testReplicationBase(t, false) } @@ -131,7 +130,7 @@ func initializeCluster(t *testing.T) (int, error) { for _, keyspaceStr := range []string{keyspace} { KeyspacePtr := &cluster.Keyspace{Name: keyspaceStr} keyspace := *KeyspacePtr - if err := clusterInstance.VtctlProcess.CreateKeyspace(keyspace.Name, sidecar.DefaultName, ""); err != nil { + if err := clusterInstance.VtctldClientProcess.CreateKeyspace(keyspace.Name, sidecar.DefaultName, ""); err != nil { return 1, err } shard := &cluster.Shard{ diff --git a/go/test/endtoend/encryption/encryptedtransport/encrypted_transport_test.go b/go/test/endtoend/encryption/encryptedtransport/encrypted_transport_test.go index 1363e07b2cd..95411536905 100644 --- a/go/test/endtoend/encryption/encryptedtransport/encrypted_transport_test.go +++ b/go/test/endtoend/encryption/encryptedtransport/encrypted_transport_test.go @@ -102,7 +102,6 @@ var ( ) func TestSecureTransport(t *testing.T) { - defer cluster.PanicHandler(t) flag.Parse() // initialize cluster @@ -139,33 +138,30 @@ func TestSecureTransport(t *testing.T) { require.NoError(t, err) } - // setup replication - var vtctlClientArgs []string + // Shared flags. + vtctldClientArgs := []string{"--server", "internal"} + vtctldClientArgs = append(vtctldClientArgs, tmclientExtraArgs("vttablet-client-1")...) - vtctlClientTmArgs := append(vtctlClientArgs, tmclientExtraArgs("vttablet-client-1")...) - - // Reparenting - vtctlClientArgs = append(vtctlClientTmArgs, "InitShardPrimary", "--", "--force", "test_keyspace/0", primaryTablet.Alias) - err = clusterInstance.VtctlProcess.ExecuteCommand(vtctlClientArgs...) + // Reparenting. + vtctlInitArgs := append(vtctldClientArgs, "InitShardPrimary", "--force", "test_keyspace/0", primaryTablet.Alias) + err = clusterInstance.VtctldClientProcess.ExecuteCommand(vtctlInitArgs...) require.NoError(t, err) err = clusterInstance.StartVTOrc("test_keyspace") require.NoError(t, err) - // Apply schema - var vtctlApplySchemaArgs = append(vtctlClientTmArgs, "ApplySchema", "--", "--sql", createVtInsertTest, "test_keyspace") - err = clusterInstance.VtctlProcess.ExecuteCommand(vtctlApplySchemaArgs...) + // Apply schema. + var vtctlApplySchemaArgs = append(vtctldClientArgs, "ApplySchema", "--sql", createVtInsertTest, "test_keyspace") + err = clusterInstance.VtctldClientProcess.ExecuteCommand(vtctlApplySchemaArgs...) require.NoError(t, err) for _, tablet := range []cluster.Vttablet{primaryTablet, replicaTablet} { - var vtctlTabletArgs []string - vtctlTabletArgs = append(vtctlTabletArgs, tmclientExtraArgs("vttablet-client-1")...) - vtctlTabletArgs = append(vtctlTabletArgs, "RunHealthCheck", tablet.Alias) - _, err = clusterInstance.VtctlProcess.ExecuteCommandWithOutput(vtctlTabletArgs...) + vtctlTabletArgs := append(vtctldClientArgs, "RunHealthCheck", tablet.Alias) + _, err = clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput(vtctlTabletArgs...) require.NoError(t, err) } - // start vtgate + // Start vtgate. clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, tabletConnExtraArgs("vttablet-client-1")...) clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, serverExtraArguments("vtgate-server-instance", "vtgate-client")...) err = clusterInstance.StartVtgate() @@ -350,7 +346,7 @@ func clusterSetUp(t *testing.T) (int, error) { for _, keyspaceStr := range []string{keyspace} { KeyspacePtr := &cluster.Keyspace{Name: keyspaceStr} keyspace := *KeyspacePtr - if err := clusterInstance.VtctlProcess.CreateKeyspace(keyspace.Name, sidecar.DefaultName, ""); err != nil { + if err := clusterInstance.VtctldClientProcess.CreateKeyspace(keyspace.Name, sidecar.DefaultName, ""); err != nil { return 1, err } shard := &cluster.Shard{ diff --git a/go/test/endtoend/keyspace/keyspace_test.go b/go/test/endtoend/keyspace/keyspace_test.go index 2a665c66214..dbabfc82d16 100644 --- a/go/test/endtoend/keyspace/keyspace_test.go +++ b/go/test/endtoend/keyspace/keyspace_test.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/json2" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" @@ -81,7 +82,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -97,7 +97,7 @@ func TestMain(m *testing.M) { return 1 } - if err := clusterForKSTest.VtctlProcess.AddCellInfo(cell2); err != nil { + if err := clusterForKSTest.VtctldClientProcess.AddCellInfo(cell2); err != nil { return 1 } @@ -139,22 +139,22 @@ func TestMain(m *testing.M) { // TestDurabilityPolicyField tests that the DurabilityPolicy field of a keyspace can be set during creation, read and updated later // from vtctld server and the vtctl binary func TestDurabilityPolicyField(t *testing.T) { - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterForKSTest.VtctldProcess.GrpcPort, clusterForKSTest.TmpDirectory) + vtctldClientProcess := clusterForKSTest.NewVtctldClientProcessInstance("localhost", clusterForKSTest.VtctldProcess.GrpcPort, clusterForKSTest.TmpDirectory) out, err := vtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", "ks_durability", "--durability-policy=semi_sync") require.NoError(t, err, out) - checkDurabilityPolicy(t, "semi_sync") + checkDurabilityPolicy(t, policy.DurabilitySemiSync) out, err = vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", "ks_durability", "--durability-policy=none") require.NoError(t, err, out) - checkDurabilityPolicy(t, "none") + checkDurabilityPolicy(t, policy.DurabilityNone) out, err = vtctldClientProcess.ExecuteCommandWithOutput("DeleteKeyspace", "ks_durability") require.NoError(t, err, out) out, err = clusterForKSTest.VtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", "--durability-policy=semi_sync", "ks_durability") require.NoError(t, err, out) - checkDurabilityPolicy(t, "semi_sync") + checkDurabilityPolicy(t, policy.DurabilitySemiSync) out, err = clusterForKSTest.VtctldClientProcess.ExecuteCommandWithOutput("DeleteKeyspace", "ks_durability") require.NoError(t, err, out) @@ -167,7 +167,6 @@ func checkDurabilityPolicy(t *testing.T, durabilityPolicy string) { } func TestGetSrvKeyspaceNames(t *testing.T) { - defer cluster.PanicHandler(t) data, err := clusterForKSTest.VtctldClientProcess.ExecuteCommandWithOutput("GetSrvKeyspaceNames", cell) require.Nil(t, err) @@ -180,7 +179,6 @@ func TestGetSrvKeyspaceNames(t *testing.T) { } func TestGetSrvKeyspacePartitions(t *testing.T) { - defer cluster.PanicHandler(t) shardedSrvKeyspace := getSrvKeyspace(t, cell, keyspaceShardedName) otherShardRefFound := false for _, partition := range shardedSrvKeyspace.Partitions { @@ -209,21 +207,18 @@ func TestGetSrvKeyspacePartitions(t *testing.T) { } func TestShardNames(t *testing.T) { - defer cluster.PanicHandler(t) output, err := clusterForKSTest.VtctldClientProcess.GetSrvKeyspaces(keyspaceShardedName, cell) require.NoError(t, err) require.NotNil(t, output[cell], "no srvkeyspace for cell %s", cell) } func TestGetKeyspace(t *testing.T) { - defer cluster.PanicHandler(t) _, err := clusterForKSTest.VtctldClientProcess.GetKeyspace(keyspaceUnshardedName) require.Nil(t, err) } func TestDeleteKeyspace(t *testing.T) { - defer cluster.PanicHandler(t) - _ = clusterForKSTest.VtctldClientProcess.CreateKeyspace("test_delete_keyspace", sidecar.DefaultName) + _ = clusterForKSTest.VtctldClientProcess.CreateKeyspace("test_delete_keyspace", sidecar.DefaultName, "") _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("CreateShard", "test_delete_keyspace/0") _ = clusterForKSTest.InitTablet(&cluster.Vttablet{ Type: "primary", @@ -245,7 +240,7 @@ func TestDeleteKeyspace(t *testing.T) { _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("DeleteKeyspace", "test_delete_keyspace") // Start over and this time use recursive DeleteKeyspace to do everything. - _ = clusterForKSTest.VtctldClientProcess.CreateKeyspace("test_delete_keyspace", sidecar.DefaultName) + _ = clusterForKSTest.VtctldClientProcess.CreateKeyspace("test_delete_keyspace", sidecar.DefaultName, "") _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("CreateShard", "test_delete_keyspace/0") _ = clusterForKSTest.InitTablet(&cluster.Vttablet{ Type: "primary", @@ -283,24 +278,24 @@ func TestDeleteKeyspace(t *testing.T) { // TODO: (ajm188) if this test gets fixed, the flags need to be updated to comply with VEP-4 as well. // tells that in zone2 after deleting shard, there is no shard #264 and in zone1 there is only 1 #269 /*func RemoveKeyspaceCell(t *testing.T) { - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("CreateKeyspace", "test_delete_keyspace_removekscell") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("CreateShard", "test_delete_keyspace_removekscell/0") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("CreateShard", "test_delete_keyspace_removekscell/1") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=0", "zone1-0000000100", "primary") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=1", "zone1-0000000101", "primary") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=0", "zone2-0000000100", "replica") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=1", "zone2-0000000101", "replica") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("CreateKeyspace", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("CreateShard", "test_delete_keyspace_removekscell/0") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("CreateShard", "test_delete_keyspace_removekscell/1") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=0", "zone1-0000000100", "primary") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=1", "zone1-0000000101", "primary") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=0", "zone2-0000000100", "replica") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("InitTablet", "--port=1234", "--bind-address=127.0.0.1", "-keyspace=test_delete_keyspace_removekscell", "--shard=1", "zone2-0000000101", "replica") // Create the serving/replication entries and check that they exist, so we can later check they're deleted. - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/1") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetSrvKeyspace", "zone2", "test_delete_keyspace_removekscell") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetSrvKeyspace", "zone1", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/1") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetSrvKeyspace", "zone2", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetSrvKeyspace", "zone1", "test_delete_keyspace_removekscell") // Just remove the shard from one cell (including tablets), // but leaving the global records and other cells/shards alone. - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("RemoveShardCell", "--recursive", "test_delete_keyspace_removekscell/0", "zone2") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("RemoveShardCell", "--recursive", "test_delete_keyspace_removekscell/0", "zone2") //Check that the shard is gone from zone2. srvKeyspaceZone2 := getSrvKeyspace(t, cell2, "test_delete_keyspace_removekscell") @@ -314,46 +309,45 @@ func TestDeleteKeyspace(t *testing.T) { assert.Equal(t, len(partition.ShardReferences), 2) } - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetKeyspace", "test_delete_keyspace_removekscell") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShard", "test_delete_keyspace_removekscell/0") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetKeyspace", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShard", "test_delete_keyspace_removekscell/0") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetTablet", "zone1-0000000100") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetTablet", "zone1-0000000100") - err := clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetTablet", "zone2-0000000100") + err := clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetTablet", "zone2-0000000100") require.Error(t, err) - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetTablet", "zone2-0000000101") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone1", "test_delete_keyspace_removekscell/0") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetTablet", "zone2-0000000101") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone1", "test_delete_keyspace_removekscell/0") - err = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") + err = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") require.Error(t, err) - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/1") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetSrvKeyspace", "zone2", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/1") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetSrvKeyspace", "zone2", "test_delete_keyspace_removekscell") // Add it back to do another test. - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("InitTablet", "--port=1234", "--keyspace=test_delete_keyspace_removekscell", "--shard=0", "zone2-0000000100", "replica") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("InitTablet", "--port=1234", "--keyspace=test_delete_keyspace_removekscell", "--shard=0", "zone2-0000000100", "replica") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") // Now use RemoveKeyspaceCell to remove all shards. - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("RemoveKeyspaceCell", "-recursive", "test_delete_keyspace_removekscell", "zone2") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone1", "test_delete_keyspace_removekscell/0") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("RemoveKeyspaceCell", "-recursive", "test_delete_keyspace_removekscell", "zone2") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("RebuildKeyspaceGraph", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone1", "test_delete_keyspace_removekscell/0") - err = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") + err = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/0") require.Error(t, err) - err = clusterForKSTest.VtctlclientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/1") + err = clusterForKSTest.VtctldClientProcess.ExecuteCommand("GetShardReplication", "zone2", "test_delete_keyspace_removekscell/1") require.Error(t, err) // Clean up - _ = clusterForKSTest.VtctlclientProcess.ExecuteCommand("DeleteKeyspace", "-recursive", "test_delete_keyspace_removekscell") + _ = clusterForKSTest.VtctldClientProcess.ExecuteCommand("DeleteKeyspace", "-recursive", "test_delete_keyspace_removekscell") } */ func TestShardCountForAllKeyspaces(t *testing.T) { - defer cluster.PanicHandler(t) testShardCountForKeyspace(t, keyspaceUnshardedName, 1) testShardCountForKeyspace(t, keyspaceShardedName, 2) } @@ -370,7 +364,6 @@ func testShardCountForKeyspace(t *testing.T, keyspace string, count int) { } func TestShardNameForAllKeyspaces(t *testing.T) { - defer cluster.PanicHandler(t) testShardNameForKeyspace(t, keyspaceUnshardedName, []string{"test_ks_unsharded"}) testShardNameForKeyspace(t, keyspaceShardedName, []string{"-80", "80-"}) } @@ -389,7 +382,6 @@ func testShardNameForKeyspace(t *testing.T, keyspace string, shardNames []string } func TestKeyspaceToShardName(t *testing.T) { - defer cluster.PanicHandler(t) var id []byte srvKeyspace := getSrvKeyspace(t, cell, keyspaceShardedName) diff --git a/go/test/endtoend/messaging/main_test.go b/go/test/endtoend/messaging/main_test.go index 49477ebe631..c654869316b 100644 --- a/go/test/endtoend/messaging/main_test.go +++ b/go/test/endtoend/messaging/main_test.go @@ -104,7 +104,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { diff --git a/go/test/endtoend/messaging/message_test.go b/go/test/endtoend/messaging/message_test.go index 7e1190c16bb..7dbef603417 100644 --- a/go/test/endtoend/messaging/message_test.go +++ b/go/test/endtoend/messaging/message_test.go @@ -84,7 +84,7 @@ func TestMessage(t *testing.T) { utils.Exec(t, conn, fmt.Sprintf("use %s", lookupKeyspace)) utils.Exec(t, conn, createMessage) - clusterInstance.VtctlProcess.ExecuteCommand(fmt.Sprintf("ReloadSchemaKeyspace %s", lookupKeyspace)) + clusterInstance.VtctldClientProcess.ExecuteCommand(fmt.Sprintf("ReloadSchemaKeyspace %s", lookupKeyspace)) defer utils.Exec(t, conn, "drop table vitess_message") @@ -375,7 +375,6 @@ func TestUnsharded(t *testing.T) { // TestReparenting checks the client connection count after reparenting. func TestReparenting(t *testing.T) { - defer cluster.PanicHandler(t) name := "sharded_message" ctx := context.Background() @@ -435,7 +434,6 @@ func TestReparenting(t *testing.T) { // TestConnection validate the connection count and message streaming. func TestConnection(t *testing.T) { - defer cluster.PanicHandler(t) name := "sharded_message" @@ -494,7 +492,6 @@ func TestConnection(t *testing.T) { } func testMessaging(t *testing.T, name, ks string) { - defer cluster.PanicHandler(t) ctx := context.Background() stream, err := VtgateGrpcConn(ctx, clusterInstance) require.Nil(t, err) diff --git a/go/test/endtoend/migration/migration_test.go b/go/test/endtoend/migration/migration_test.go index eca112e388d..54afd2cb3ee 100644 --- a/go/test/endtoend/migration/migration_test.go +++ b/go/test/endtoend/migration/migration_test.go @@ -132,10 +132,6 @@ three streams although only two are required. This is to show that there can exi streams from the same source. The main difference between an external source vs a vitess source is that the source proto contains an "external_mysql" field instead of keyspace and shard. That field is the key into the externalConnections section of the input yaml. - -VReplicationExec: insert into _vt.vreplication (workflow, db_name, source, pos, max_tps, max_replication_lag, tablet_types, time_updated, transaction_timestamp, state) values('product', 'vt_commerce', 'filter: > external_mysql:\"product\" ', ”, 9999, 9999, 'primary', 0, 0, 'Running') -VReplicationExec: insert into _vt.vreplication (workflow, db_name, source, pos, max_tps, max_replication_lag, tablet_types, time_updated, transaction_timestamp, state) values('customer', 'vt_commerce', 'filter: > external_mysql:\"customer\" ', ”, 9999, 9999, 'primary', 0, 0, 'Running') -VReplicationExec: insert into _vt.vreplication (workflow, db_name, source, pos, max_tps, max_replication_lag, tablet_types, time_updated, transaction_timestamp, state) values('orders', 'vt_commerce', 'filter: > external_mysql:\"customer\" ', ”, 9999, 9999, 'primary', 0, 0, 'Running') */ func TestMigration(t *testing.T) { yamlFile := startCluster(t) @@ -155,7 +151,7 @@ func TestMigration(t *testing.T) { migrate(t, "customer", "commerce", []string{"customer"}) migrate(t, "customer", "commerce", []string{"orders"}) vttablet := keyspaces["commerce"].Shards[0].Vttablets[0].VttabletProcess - waitForVReplicationToCatchup(t, vttablet, 1*time.Second) + waitForVReplicationToCatchup(t, vttablet, 30*time.Second) testcases := []struct { query string @@ -217,11 +213,11 @@ func migrate(t *testing.T, fromdb, toks string, tables []string) { var sqlEscaped bytes.Buffer val.EncodeSQL(&sqlEscaped) query := fmt.Sprintf("insert into _vt.vreplication "+ - "(workflow, db_name, source, pos, max_tps, max_replication_lag, tablet_types, time_updated, transaction_timestamp, state) values"+ - "('%s', '%s', %s, '', 9999, 9999, 'primary', 0, 0, 'Running')", tables[0], "vt_"+toks, sqlEscaped.String()) - fmt.Printf("VReplicationExec: %s\n", query) - vttablet := keyspaces[toks].Shards[0].Vttablets[0].VttabletProcess - err := clusterInstance.VtctldClientProcess.ExecuteCommand("VReplicationExec", vttablet.TabletPath, query) + "(workflow, db_name, source, pos, max_tps, max_replication_lag, tablet_types, time_updated, transaction_timestamp, state, options) values"+ + "('%s', '%s', %s, '', 9999, 9999, 'primary', 0, 0, 'Running', '{}')", tables[0], "vt_"+toks, sqlEscaped.String()) + fmt.Printf("VReplication insert: %s\n", query) + vttablet := keyspaces[toks].Shards[0].Vttablets[0].Alias + err := clusterInstance.VtctldClientProcess.ExecuteCommand("ExecuteFetchAsDBA", vttablet, query) require.NoError(t, err) } diff --git a/go/test/endtoend/mysqlctl/mysqlctl_test.go b/go/test/endtoend/mysqlctl/mysqlctl_test.go index f93724fa4a8..f5f08bf98e9 100644 --- a/go/test/endtoend/mysqlctl/mysqlctl_test.go +++ b/go/test/endtoend/mysqlctl/mysqlctl_test.go @@ -40,7 +40,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -53,7 +52,7 @@ func TestMain(m *testing.M) { return 1 } - if err := clusterInstance.VtctlProcess.CreateKeyspace(keyspaceName, sidecar.DefaultName, ""); err != nil { + if err := clusterInstance.VtctldClientProcess.CreateKeyspace(keyspaceName, sidecar.DefaultName, ""); err != nil { return 1 } @@ -139,7 +138,6 @@ func initCluster(shardNames []string, totalTabletsRequired int) { } func TestRestart(t *testing.T) { - defer cluster.PanicHandler(t) err := primaryTablet.MysqlctlProcess.Stop() require.NoError(t, err) primaryTablet.MysqlctlProcess.CleanupFiles(primaryTablet.TabletUID) @@ -148,7 +146,6 @@ func TestRestart(t *testing.T) { } func TestAutoDetect(t *testing.T) { - defer cluster.PanicHandler(t) err := clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].VttabletProcess.Setup() require.NoError(t, err) diff --git a/go/test/endtoend/mysqlctld/mysqlctld_test.go b/go/test/endtoend/mysqlctld/mysqlctld_test.go index beb155830e2..3d4b8e70a76 100644 --- a/go/test/endtoend/mysqlctld/mysqlctld_test.go +++ b/go/test/endtoend/mysqlctld/mysqlctld_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -57,7 +56,7 @@ func TestMain(m *testing.M) { return 1 } - if err := clusterInstance.VtctlProcess.CreateKeyspace(keyspaceName, sidecar.DefaultName, ""); err != nil { + if err := clusterInstance.VtctldClientProcess.CreateKeyspace(keyspaceName, sidecar.DefaultName, ""); err != nil { return 1 } @@ -141,7 +140,6 @@ func initCluster(shardNames []string, totalTabletsRequired int) error { } func TestRestart(t *testing.T) { - defer cluster.PanicHandler(t) err := primaryTablet.MysqlctldProcess.Stop() require.Nil(t, err) require.Truef(t, primaryTablet.MysqlctldProcess.WaitForMysqlCtldShutdown(), "Mysqlctld has not stopped...") @@ -151,7 +149,6 @@ func TestRestart(t *testing.T) { } func TestAutoDetect(t *testing.T) { - defer cluster.PanicHandler(t) err := clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].VttabletProcess.Setup() require.Nil(t, err, "error should be nil") diff --git a/go/test/endtoend/mysqlserver/main_test.go b/go/test/endtoend/mysqlserver/main_test.go index 18b169e33d7..20da69e18e8 100644 --- a/go/test/endtoend/mysqlserver/main_test.go +++ b/go/test/endtoend/mysqlserver/main_test.go @@ -61,7 +61,6 @@ END; ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() // setting grpc max size diff --git a/go/test/endtoend/mysqlserver/mysql_server_test.go b/go/test/endtoend/mysqlserver/mysql_server_test.go index 6b691582c66..ee6e973593b 100644 --- a/go/test/endtoend/mysqlserver/mysql_server_test.go +++ b/go/test/endtoend/mysqlserver/mysql_server_test.go @@ -35,14 +35,12 @@ import ( "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" _ "github.com/go-sql-driver/mysql" ) // TestMultiStmt checks that multiStatements=True and multiStatements=False work properly. func TestMultiStatement(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() // connect database with multiStatements=True @@ -70,7 +68,6 @@ func TestMultiStatement(t *testing.T) { // TestLargeComment add large comment in insert stmt and validate the insert process. func TestLargeComment(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) @@ -89,7 +86,6 @@ func TestLargeComment(t *testing.T) { // TestInsertLargerThenGrpcLimit insert blob larger then grpc limit and verify the error. func TestInsertLargerThenGrpcLimit(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() @@ -109,7 +105,6 @@ func TestInsertLargerThenGrpcLimit(t *testing.T) { // TestTimeout executes sleep(5) with query_timeout of 1 second, and verifies the error. func TestTimeout(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) @@ -125,7 +120,6 @@ func TestTimeout(t *testing.T) { // TestInvalidField tries to fetch invalid column and verifies the error. func TestInvalidField(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) @@ -141,7 +135,6 @@ func TestInvalidField(t *testing.T) { // TestWarnings validates the behaviour of SHOW WARNINGS. func TestWarnings(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) @@ -183,7 +176,6 @@ func TestWarnings(t *testing.T) { // TestSelectWithUnauthorizedUser verifies that an unauthorized user // is not able to read from the table. func TestSelectWithUnauthorizedUser(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() tmpVtParam := vtParams @@ -202,7 +194,6 @@ func TestSelectWithUnauthorizedUser(t *testing.T) { // TestPartitionedTable validates that partitioned tables are recognized by schema engine func TestPartitionedTable(t *testing.T) { - defer cluster.PanicHandler(t) tablet := clusterInstance.Keyspaces[0].Shards[0].PrimaryTablet() diff --git a/go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go b/go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go index 035789e4b87..d34b63b833b 100644 --- a/go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go +++ b/go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go @@ -120,7 +120,6 @@ const ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -197,7 +196,6 @@ func TestMain(m *testing.M) { } func TestOnlineDDLFlow(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() require.NotNil(t, clusterInstance) @@ -246,7 +244,7 @@ func TestOnlineDDLFlow(t *testing.T) { select { case <-ticker.C: case <-workloadCtx.Done(): - t.Logf("Terminating routine throttler check") + fmt.Println("Terminating routine throttler check") return } } @@ -260,8 +258,8 @@ func TestOnlineDDLFlow(t *testing.T) { wg.Add(1) go func() { defer cancel() - defer t.Logf("Terminating workload") defer wg.Done() + defer fmt.Println("Terminating workload") runMultipleConnections(workloadCtx, t) }() }) diff --git a/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go b/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go index 970d79a6e45..41acd0dea4e 100644 --- a/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go +++ b/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go @@ -137,7 +137,6 @@ type revertibleTestCase struct { } func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -204,7 +203,6 @@ func TestMain(m *testing.M) { } func TestRevertSchemaChanges(t *testing.T) { - defer cluster.PanicHandler(t) shards = clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) @@ -261,6 +259,11 @@ func testRevertible(t *testing.T) { toSchema: `id int primary key, i2 int default null`, removedUniqueKeyNames: `i1_uidx`, }, + { + name: "removed expression unique key, skipped", + fromSchema: `id int primary key, i1 int default null, unique key idx1 ((id + 1))`, + toSchema: `id int primary key, i2 int default null`, + }, { name: "expanding unique key removes unique constraint", fromSchema: `id int primary key, i1 int default null, unique key i1_uidx(i1)`, diff --git a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go index 53a1c8137fd..8547431ddd3 100644 --- a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go +++ b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go @@ -239,7 +239,6 @@ func waitForMessage(t *testing.T, uuid string, messageSubstring string) { } func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -321,7 +320,6 @@ func TestSchedulerSchemaChanges(t *testing.T) { } func testScheduler(t *testing.T) { - defer cluster.PanicHandler(t) shards = clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) @@ -716,6 +714,89 @@ func testScheduler(t *testing.T) { } }) }) + t.Run("force_cutover mdl", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), extendedWaitTime*5) + defer cancel() + + t1uuid = testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy+" --postpone-completion", "vtgate", "", "", true)) // skip wait + + t.Run("wait for t1 running", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusRunning) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + }) + t.Run("wait for t1 ready to complete", func(t *testing.T) { + // Waiting for 'running', above, is not enough. We want to let vreplication a chance to start running, or else + // we attempt the cut-over too early. Specifically in this test, we're going to lock rows FOR UPDATE, which, + // if vreplication does not get the chance to start, will prevent it from doing anything at all. + // ready_to_complete is a great signal for us that vreplication is healthy and up to date. + waitForReadyToComplete(t, t1uuid, true) + }) + + conn, err := primaryTablet.VttabletProcess.TabletConn(keyspaceName, true) + require.NoError(t, err) + defer conn.Close() + + unlockTables := func() error { + _, err := conn.ExecuteFetch("unlock tables", 0, false) + return err + } + t.Run("locking table", func(t *testing.T) { + _, err := conn.ExecuteFetch("lock tables t1_test write", 0, false) + require.NoError(t, err) + }) + defer unlockTables() + t.Run("injecting heartbeats asynchronously", func(t *testing.T) { + go func() { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + throttler.CheckThrottler(clusterInstance, primaryTablet, throttlerapp.OnlineDDLName, nil) + select { + case <-ticker.C: + case <-ctx.Done(): + return + } + } + }() + }) + t.Run("check no force_cutover", func(t *testing.T) { + rs := onlineddl.ReadMigrations(t, &vtParams, t1uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + forceCutOver := row.AsInt64("force_cutover", 0) + assert.Equal(t, int64(0), forceCutOver) // disabled + } + }) + t.Run("attempt to complete", func(t *testing.T) { + onlineddl.CheckCompleteMigration(t, &vtParams, shards, t1uuid, true) + }) + t.Run("cut-over fail due to timeout", func(t *testing.T) { + waitForMessage(t, t1uuid, "(errno 3024) (sqlstate HY000): Query execution was interrupted, maximum statement execution time exceeded") + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed, schema.OnlineDDLStatusRunning) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusRunning) + }) + t.Run("force_cutover", func(t *testing.T) { + onlineddl.CheckForceMigrationCutOver(t, &vtParams, shards, t1uuid, true) + }) + t.Run("check force_cutover", func(t *testing.T) { + rs := onlineddl.ReadMigrations(t, &vtParams, t1uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + forceCutOver := row.AsInt64("force_cutover", 0) + assert.Equal(t, int64(1), forceCutOver) // enabled + } + }) + t.Run("expect completion", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusComplete) + }) + t.Run("expect unlock failure", func(t *testing.T) { + err := unlockTables() + assert.ErrorContains(t, err, "broken pipe") + }) + }) } t.Run("ALTER both tables non-concurrent", func(t *testing.T) { t1uuid = testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy, "vtgate", "", "", true)) // skip wait @@ -1593,7 +1674,6 @@ func testScheduler(t *testing.T) { } func testSingleton(t *testing.T) { - defer cluster.PanicHandler(t) shards = clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) @@ -1844,7 +1924,6 @@ DROP TABLE IF EXISTS stress_test }) } func testDeclarative(t *testing.T) { - defer cluster.PanicHandler(t) shards = clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) @@ -2516,7 +2595,6 @@ func testDeclarative(t *testing.T) { } func testForeignKeys(t *testing.T) { - defer cluster.PanicHandler(t) var ( createStatements = []string{ diff --git a/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go b/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go index 92dfa2b0c4a..a7c38527152 100644 --- a/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go +++ b/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go @@ -160,7 +160,6 @@ const ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -224,7 +223,6 @@ func TestMain(m *testing.M) { } func TestVreplSchemaChanges(t *testing.T) { - defer cluster.PanicHandler(t) shards = clusterInstance.Keyspaces[0].Shards require.Equal(t, 2, len(shards)) diff --git a/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go b/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go index 88c145dc40c..f7b222c175d 100644 --- a/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go +++ b/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go @@ -159,7 +159,6 @@ func nextOpOrder() int64 { } func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -226,7 +225,6 @@ func TestMain(m *testing.M) { } func TestVreplMiniStressSchemaChanges(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() diff --git a/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go b/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go index 85b3585beb4..1e52db38bd0 100644 --- a/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go +++ b/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go @@ -407,7 +407,6 @@ func mysqlParams() *mysql.ConnParams { } func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -478,7 +477,6 @@ func TestMain(m *testing.M) { } func TestVreplStressSchemaChanges(t *testing.T) { - defer cluster.PanicHandler(t) shards = clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go index 972421c96da..4a2f7f1a3ce 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go +++ b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go @@ -67,7 +67,6 @@ const ( // Use $VREPL_SUITE_TEST_FILTER environment variable to filter tests by name. func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() testsFilter = os.Getenv(testFilterEnvVar) @@ -133,7 +132,6 @@ func TestMain(m *testing.M) { } func TestVreplSuiteSchemaChanges(t *testing.T) { - defer cluster.PanicHandler(t) shards := clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) diff --git a/go/test/endtoend/preparestmt/benchmark_test.go b/go/test/endtoend/preparestmt/benchmark_test.go new file mode 100644 index 00000000000..fcf10a6948a --- /dev/null +++ b/go/test/endtoend/preparestmt/benchmark_test.go @@ -0,0 +1,144 @@ +/* +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 preparestmt + +import ( + "math/rand/v2" + "testing" + + "github.com/icrowley/fake" +) + +/* +export ver=v1 p=~/benchmark && go test \ +-run '^$' -bench '^BenchmarkPreparedStmt' \ +-benchtime 2s -count 6 -cpu 4 \ +| tee $p/${ver}.txt +*/ +func BenchmarkPreparedStmt(b *testing.B) { + dbo := Connect(b) + defer dbo.Close() + + // prepare statement + insertStmt := `insert into sks.t1 (name, age, email, created_at, is_active) values(?, ?, ?, current_timestamp, ?)` + selectStmt := `select id, name, age, email from sks.t1 where age between ? and ? and is_active = ? limit ?` + updateStmt := `update sks.t1 set is_active = ? where id = ?` + deleteStmt := `delete from sks.t1 where is_active = ? and age = ?` + + joinStmt := `SELECT + user.id AS user_id +FROM + sks.t1 AS user +LEFT JOIN + sks.t1 AS parent ON user.id = parent.id AND parent.age = ? +LEFT JOIN + sks.t1 AS manager ON user.id = manager.id AND manager.is_active = ? +LEFT JOIN + sks.t1 AS child ON user.id = child.id +WHERE + user.is_active = ? + AND user.id = ? + AND parent.id = ? + AND manager.id = ?` + + iStmt, err := dbo.Prepare(insertStmt) + if err != nil { + b.Fatal(err) + } + defer iStmt.Close() + + b.Run("Insert", func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := iStmt.Exec(fake.FirstName(), rand.IntN(100), fake.EmailAddress(), rand.IntN(2)) + if err != nil { + b.Fatal(err) + } + } + }) + + sStmt, err := dbo.Prepare(selectStmt) + if err != nil { + b.Fatal(err) + } + defer sStmt.Close() + + b.Run("Select", func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + age := rand.IntN(80) + r, err := sStmt.Query(age, age+20, rand.IntN(2), rand.IntN(10)) + if err != nil { + b.Fatal(err) + } + r.Close() + } + }) + + jStmt, err := dbo.Prepare(joinStmt) + if err != nil { + b.Fatal(err) + } + defer jStmt.Close() + + b.Run("Join Select:Simple Route", func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + age := rand.IntN(80) + active := rand.IntN(2) + id := rand.IntN(2000) + r, err := jStmt.Query(age, active, active, id, id, id) + if err != nil { + b.Fatal(err) + } + r.Close() + } + }) + + uStmt, err := dbo.Prepare(updateStmt) + if err != nil { + b.Fatal(err) + } + defer sStmt.Close() + + b.Run("Update", func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err = uStmt.Exec(rand.IntN(2), rand.IntN(2000)) + if err != nil { + b.Fatal(err) + } + } + }) + + dStmt, err := dbo.Prepare(deleteStmt) + if err != nil { + b.Fatal(err) + } + defer sStmt.Close() + + b.Run("Delete", func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err = dStmt.Exec(rand.IntN(2), rand.IntN(100)) + if err != nil { + b.Fatal(err) + } + } + }) + +} diff --git a/go/test/endtoend/preparestmt/main_test.go b/go/test/endtoend/preparestmt/main_test.go index 018e9d266fd..dd0094fe825 100644 --- a/go/test/endtoend/preparestmt/main_test.go +++ b/go/test/endtoend/preparestmt/main_test.go @@ -18,6 +18,7 @@ package preparestmt import ( "database/sql" + _ "embed" "flag" "fmt" "os" @@ -51,7 +52,7 @@ type DBInfo struct { } func init() { - dbInfo.KeyspaceName = keyspaceName + dbInfo.KeyspaceName = uks dbInfo.Username = "testuser1" dbInfo.Password = "testpassword1" dbInfo.Params = []string{ @@ -65,9 +66,9 @@ var ( clusterInstance *cluster.LocalProcessCluster dbInfo DBInfo hostname = "localhost" - keyspaceName = "test_keyspace" + uks = "uks" + sks = "sks" testingID = 1 - tableName = "vt_prepare_stmt_test" cell = "zone1" mysqlAuthServerStatic = "mysql_auth_server_static.json" jsonExample = `{ @@ -108,61 +109,21 @@ var ( } } }` - sqlSchema = `create table ` + tableName + ` ( - id bigint auto_increment, - msg varchar(64), - keyspace_id bigint(20) unsigned NOT NULL, - tinyint_unsigned TINYINT, - bool_signed BOOL, - smallint_unsigned SMALLINT, - mediumint_unsigned MEDIUMINT, - int_unsigned INT, - float_unsigned FLOAT(10,2), - double_unsigned DOUBLE(16,2), - decimal_unsigned DECIMAL, - t_date DATE, - t_datetime DATETIME, - t_datetime_micros DATETIME(6), - t_time TIME, - t_timestamp TIMESTAMP, - c8 bit(8) DEFAULT NULL, - c16 bit(16) DEFAULT NULL, - c24 bit(24) DEFAULT NULL, - c32 bit(32) DEFAULT NULL, - c40 bit(40) DEFAULT NULL, - c48 bit(48) DEFAULT NULL, - c56 bit(56) DEFAULT NULL, - c63 bit(63) DEFAULT NULL, - c64 bit(64) DEFAULT NULL, - json_col JSON, - text_col TEXT, - data longblob, - tinyint_min TINYINT, - tinyint_max TINYINT, - tinyint_pos TINYINT, - tinyint_neg TINYINT, - smallint_min SMALLINT, - smallint_max SMALLINT, - smallint_pos SMALLINT, - smallint_neg SMALLINT, - medint_min MEDIUMINT, - medint_max MEDIUMINT, - medint_pos MEDIUMINT, - medint_neg MEDIUMINT, - int_min INT, - int_max INT, - int_pos INT, - int_neg INT, - bigint_min BIGINT, - bigint_max BIGINT, - bigint_pos BIGINT, - bigint_neg BIGINT, - primary key (id) - ) Engine=InnoDB` + + //go:embed uSchema.sql + uSQLSchema string + + //go:embed uVschema.json + uVschema string + + //go:embed sSchema.sql + sSQLSchema string + + //go:embed sVschema.json + sVschema string ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -186,15 +147,13 @@ func TestMain(m *testing.M) { } // Start keyspace - keyspace := &cluster.Keyspace{ - Name: keyspaceName, - SchemaSQL: sqlSchema, - } - uks := &cluster.Keyspace{Name: "uks"} - if err := clusterInstance.StartUnshardedKeyspace(*keyspace, 1, false); err != nil { + ks := cluster.Keyspace{Name: uks, SchemaSQL: uSQLSchema, VSchema: uVschema} + if err := clusterInstance.StartUnshardedKeyspace(ks, 1, false); err != nil { return 1, err } - if err := clusterInstance.StartUnshardedKeyspace(*uks, 0, false); err != nil { + + ks = cluster.Keyspace{Name: sks, SchemaSQL: sSQLSchema, VSchema: sVschema} + if err := clusterInstance.StartKeyspace(ks, []string{"-"}, 0, false); err != nil { return 1, err } @@ -204,7 +163,8 @@ func TestMain(m *testing.M) { vtgateInstance.ExtraArgs = []string{ "--mysql_server_query_timeout", "1s", "--mysql_auth_server_static_file", clusterInstance.TmpDirectory + "/" + mysqlAuthServerStatic, - "--mysql_server_version", "8.0.16-7", + "--pprof-http", + "--schema_change_signal=false", } // Start vtgate @@ -252,7 +212,7 @@ func createConfig(name, data string) error { } // Connect will connect the vtgate through mysql protocol. -func Connect(t *testing.T, params ...string) *sql.DB { +func Connect(t testing.TB, params ...string) *sql.DB { dbo, err := sql.Open("mysql", dbInfo.ConnectionString(params...)) require.Nil(t, err) return dbo @@ -286,7 +246,7 @@ func execErr(dbo *sql.DB, stmt string, params ...any) *mysql.MySQLError { func selectWhere(t *testing.T, dbo *sql.DB, where string, params ...any) []tableData { var out []tableData // prepare query - qry := "SELECT msg, data, text_col, t_datetime, t_datetime_micros FROM " + tableName + qry := "SELECT msg, data, text_col, t_datetime, t_datetime_micros FROM vt_prepare_stmt_test" if where != "" { qry += " WHERE (" + where + ")" } @@ -308,7 +268,7 @@ func selectWhere(t *testing.T, dbo *sql.DB, where string, params ...any) []table func selectWhereWithTx(t *testing.T, tx *sql.Tx, where string, params ...any) []tableData { var out []tableData // prepare query - qry := "SELECT msg, data, text_col, t_datetime, t_datetime_micros FROM " + tableName + qry := "SELECT msg, data, text_col, t_datetime, t_datetime_micros FROM vt_prepare_stmt_test" if where != "" { qry += " WHERE (" + where + ")" } diff --git a/go/test/endtoend/preparestmt/sSchema.sql b/go/test/endtoend/preparestmt/sSchema.sql new file mode 100644 index 00000000000..7da6b759a9a --- /dev/null +++ b/go/test/endtoend/preparestmt/sSchema.sql @@ -0,0 +1,10 @@ +CREATE TABLE t1 +( + id BIGINT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + age INT, + email VARCHAR(100), + created_at DATETIME, + is_active BOOLEAN, + INDEX age_idx (age) +); \ No newline at end of file diff --git a/go/test/endtoend/preparestmt/sVschema.json b/go/test/endtoend/preparestmt/sVschema.json new file mode 100644 index 00000000000..77801827d42 --- /dev/null +++ b/go/test/endtoend/preparestmt/sVschema.json @@ -0,0 +1,22 @@ +{ + "sharded": true, + "vindexes": { + "xxhash": { + "type": "xxhash" + } + }, + "tables": { + "t1": { + "column_vindexes": [ + { + "column": "id", + "name": "xxhash" + } + ], + "auto_increment":{ + "column" : "id", + "sequence" : "uks.t1_seq" + } + } + } +} diff --git a/go/test/endtoend/preparestmt/stmt_methods_test.go b/go/test/endtoend/preparestmt/stmt_methods_test.go index 24fb58bff81..e8e001fdca7 100644 --- a/go/test/endtoend/preparestmt/stmt_methods_test.go +++ b/go/test/endtoend/preparestmt/stmt_methods_test.go @@ -27,20 +27,16 @@ import ( "github.com/icrowley/fake" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/test/endtoend/cluster" ) // TestSelect simple select the data without any condition. func TestSelect(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() selectWhere(t, dbo, "") } func TestSelectDatabase(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() prepare, err := dbo.Prepare("select database()") @@ -52,17 +48,16 @@ func TestSelectDatabase(t *testing.T) { require.True(t, rows.Next(), "no rows found") err = rows.Scan(&resultBytes) require.NoError(t, err) - assert.Equal(t, string(resultBytes), "test_keyspace") + assert.Equal(t, string(resultBytes), "uks") } // TestInsertUpdateDelete validates all insert, update and // delete method on prepared statements. func TestInsertUpdateDelete(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() // prepare insert statement - insertStmt := `insert into ` + tableName + ` values( ?, ?, ?, ?, ?, ?, ?, ?, + insertStmt := `insert into vt_prepare_stmt_test values( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);` @@ -134,8 +129,7 @@ func testReplica(t *testing.T) { // testcount validates inserted rows count with expected count. func testcount(t *testing.T, dbo *sql.DB, except int) { - defer cluster.PanicHandler(t) - r, err := dbo.Query("SELECT count(1) FROM " + tableName) + r, err := dbo.Query("SELECT count(1) FROM vt_prepare_stmt_test") require.Nil(t, err) r.Next() @@ -148,11 +142,10 @@ func testcount(t *testing.T, dbo *sql.DB, except int) { // TestAutoIncColumns test insertion of row without passing // the value of auto increment columns (here it is id). func TestAutoIncColumns(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() // insert a row without id - insertStmt := "INSERT INTO " + tableName + ` ( + insertStmt := "INSERT INTO vt_prepare_stmt_test" + ` ( msg,keyspace_id,tinyint_unsigned,bool_signed,smallint_unsigned, mediumint_unsigned,int_unsigned,float_unsigned,double_unsigned, decimal_unsigned,t_date,t_datetime,t_datetime_micros,t_time,t_timestamp,c8,c16,c24, @@ -187,7 +180,7 @@ func TestAutoIncColumns(t *testing.T) { // deleteRecord test deletion operation corresponds to the testingID. func deleteRecord(t *testing.T, dbo *sql.DB) { // delete the record with id 1 - exec(t, dbo, "DELETE FROM "+tableName+" WHERE id = ?;", testingID) + exec(t, dbo, "DELETE FROM vt_prepare_stmt_test WHERE id = ?;", testingID) data := selectWhere(t, dbo, "id = ?", testingID) assert.Equal(t, 0, len(data)) @@ -199,7 +192,7 @@ func updateRecord(t *testing.T, dbo *sql.DB) { // update the record with id 1 updateData := "new data value" updateTextCol := "new text col value" - updateQuery := "update " + tableName + " set data = ? , text_col = ? where id = ?;" + updateQuery := "update vt_prepare_stmt_test set data = ? , text_col = ? where id = ?;" exec(t, dbo, updateQuery, updateData, updateTextCol, testingID) @@ -227,14 +220,13 @@ func reconnectAndTest(t *testing.T) { // TestColumnParameter query database using column // parameter. func TestColumnParameter(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() id := 1000 parameter1 := "param1" message := "TestColumnParameter" - insertStmt := "INSERT INTO " + tableName + " (id, msg, keyspace_id) VALUES (?, ?, ?);" + insertStmt := "INSERT INTO vt_prepare_stmt_test (id, msg, keyspace_id) VALUES (?, ?, ?);" values := []any{ id, message, @@ -245,7 +237,7 @@ func TestColumnParameter(t *testing.T) { var param, msg string var recID int - selectStmt := "SELECT COALESCE(?, id), msg FROM " + tableName + " WHERE msg = ? LIMIT ?" + selectStmt := "SELECT COALESCE(?, id), msg FROM vt_prepare_stmt_test WHERE msg = ? LIMIT ?" results1, err := dbo.Query(selectStmt, parameter1, message, 1) require.Nil(t, err) @@ -267,7 +259,6 @@ func TestColumnParameter(t *testing.T) { // TestWrongTableName query database using invalid // tablename and validate error. func TestWrongTableName(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() execWithError(t, dbo, []uint16{1146}, "select * from teseting_table;") @@ -319,14 +310,10 @@ func getStringToString(x sql.NullString) string { } func TestSelectDBA(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() - _, err := dbo.Exec("use uks") - require.NoError(t, err) - - _, err = dbo.Exec("CREATE TABLE `a` (`one` int NOT NULL,`two` int NOT NULL,PRIMARY KEY(`one`, `two`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4") + _, err := dbo.Exec("CREATE TABLE `a` (`one` int NOT NULL,`two` int NOT NULL,PRIMARY KEY(`one`, `two`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4") require.NoError(t, err) prepare, err := dbo.Prepare(`SELECT @@ -342,10 +329,10 @@ func TestSelectDBA(t *testing.T) { extra extra, table_name table_name FROM information_schema.columns - WHERE table_schema = ? + WHERE table_schema = ? and table_name = ? ORDER BY ordinal_position`) require.NoError(t, err) - rows, err := prepare.Query("uks") + rows, err := prepare.Query("uks", "a") require.NoError(t, err) defer rows.Close() var rec columns @@ -381,7 +368,6 @@ func TestSelectDBA(t *testing.T) { } func TestSelectLock(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() @@ -417,7 +403,6 @@ func TestSelectLock(t *testing.T) { } func TestShowColumns(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t) defer dbo.Close() @@ -438,7 +423,6 @@ func TestShowColumns(t *testing.T) { } func TestBinaryColumn(t *testing.T) { - defer cluster.PanicHandler(t) dbo := Connect(t, "interpolateParams=false") defer dbo.Close() @@ -454,6 +438,6 @@ func TestBinaryColumn(t *testing.T) { AND column_info.table_schema = ? -- Exclude views. AND table_info.table_type = 'BASE TABLE' - ORDER BY BINARY table_info.table_name`, keyspaceName, keyspaceName) + ORDER BY BINARY table_info.table_name`, uks, uks) require.NoError(t, err) } diff --git a/go/test/endtoend/preparestmt/uSchema.sql b/go/test/endtoend/preparestmt/uSchema.sql new file mode 100644 index 00000000000..5284cacded6 --- /dev/null +++ b/go/test/endtoend/preparestmt/uSchema.sql @@ -0,0 +1,56 @@ +create table vt_prepare_stmt_test +( + id bigint auto_increment, + msg varchar(64), + keyspace_id bigint(20) unsigned NOT NULL, + tinyint_unsigned TINYINT, + bool_signed BOOL, + smallint_unsigned SMALLINT, + mediumint_unsigned MEDIUMINT, + int_unsigned INT, + float_unsigned FLOAT(10, 2), + double_unsigned DOUBLE(16, 2), + decimal_unsigned DECIMAL, + t_date DATE, + t_datetime DATETIME, + t_datetime_micros DATETIME(6), + t_time TIME, + t_timestamp TIMESTAMP, + c8 bit(8) DEFAULT NULL, + c16 bit(16) DEFAULT NULL, + c24 bit(24) DEFAULT NULL, + c32 bit(32) DEFAULT NULL, + c40 bit(40) DEFAULT NULL, + c48 bit(48) DEFAULT NULL, + c56 bit(56) DEFAULT NULL, + c63 bit(63) DEFAULT NULL, + c64 bit(64) DEFAULT NULL, + json_col JSON, + text_col TEXT, + data longblob, + tinyint_min TINYINT, + tinyint_max TINYINT, + tinyint_pos TINYINT, + tinyint_neg TINYINT, + smallint_min SMALLINT, + smallint_max SMALLINT, + smallint_pos SMALLINT, + smallint_neg SMALLINT, + medint_min MEDIUMINT, + medint_max MEDIUMINT, + medint_pos MEDIUMINT, + medint_neg MEDIUMINT, + int_min INT, + int_max INT, + int_pos INT, + int_neg INT, + bigint_min BIGINT, + bigint_max BIGINT, + bigint_pos BIGINT, + bigint_neg BIGINT, + primary key (id) +) Engine = InnoDB; + +CREATE TABLE t1_seq ( id INT, next_id BIGINT, cache BIGINT, PRIMARY KEY(id)) comment 'vitess_sequence'; + +INSERT INTO t1_seq (id, next_id, cache) values (0, 1, 500000); \ No newline at end of file diff --git a/go/test/endtoend/preparestmt/uVschema.json b/go/test/endtoend/preparestmt/uVschema.json new file mode 100644 index 00000000000..1f4de22e018 --- /dev/null +++ b/go/test/endtoend/preparestmt/uVschema.json @@ -0,0 +1,8 @@ +{ + "sharded": false, + "tables": { + "sequence_test_seq": { + "type": "sequence" + } + } +} diff --git a/go/test/endtoend/recovery/pitr/binlog_server.go b/go/test/endtoend/recovery/pitr/binlog_server.go deleted file mode 100644 index 3b78b0d4ad7..00000000000 --- a/go/test/endtoend/recovery/pitr/binlog_server.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright 2020 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 pitr - -import ( - "fmt" - "os" - "os/exec" - "path" - "strings" - "syscall" - "time" - - "vitess.io/vitess/go/vt/log" -) - -const ( - binlogExecutableName = "rippled" - binlogDataDir = "binlog_dir" - binlogUser = "ripple" - binlogPassword = "ripplepassword" - binlogPasswordHash = "D4CDF66E273494CEA9592162BEBB6D62D94C4168" -) - -type binLogServer struct { - hostname string - port int - username string - password string - passwordHash string - dataDirectory string - executablePath string - - proc *exec.Cmd - exit chan error -} - -type mysqlSource struct { - hostname string - port int - username string - password string -} - -// newBinlogServer returns an instance of binlog server -func newBinlogServer(hostname string, port int) (*binLogServer, error) { - dataDir := path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("%s_%d", binlogDataDir, port)) - fmt.Println(dataDir) - if _, err := os.Stat(dataDir); os.IsNotExist(err) { - err := os.Mkdir(dataDir, 0700) - if err != nil { - log.Error(err) - return nil, err - } - } - return &binLogServer{ - executablePath: path.Join(os.Getenv("EXTRA_BIN"), binlogExecutableName), - dataDirectory: dataDir, - username: binlogUser, - password: binlogPassword, - passwordHash: binlogPasswordHash, - hostname: hostname, - port: port, - }, nil -} - -// start starts the binlog server points to running mysql port -func (bs *binLogServer) start(source mysqlSource) error { - bs.proc = exec.Command( - bs.executablePath, - fmt.Sprintf("-ripple_datadir=%s", bs.dataDirectory), - fmt.Sprintf("-ripple_server_password_hash=%s", bs.passwordHash), - fmt.Sprintf("-ripple_master_address=%s", source.hostname), - fmt.Sprintf("-ripple_master_port=%d", source.port), - fmt.Sprintf("-ripple_master_user=%s", source.username), - fmt.Sprintf("-ripple_server_ports=%d", bs.port), - ) - if source.password != "" { - bs.proc.Args = append(bs.proc.Args, fmt.Sprintf("-ripple_master_password=%s", source.password)) - } - - errFile, err := os.Create(path.Join(bs.dataDirectory, "log.txt")) - if err != nil { - log.Errorf("cannot create error log file for binlog server: %v", err) - return err - } - bs.proc.Stderr = errFile - - bs.proc.Env = append(bs.proc.Env, os.Environ()...) - - log.Infof("Running binlog server with command: %v", strings.Join(bs.proc.Args, " ")) - - err = bs.proc.Start() - if err != nil { - return err - } - bs.exit = make(chan error) - go func() { - if bs.proc != nil { - bs.exit <- bs.proc.Wait() - } - }() - return nil -} - -func (bs *binLogServer) stop() error { - if bs.proc == nil || bs.exit == nil { - return nil - } - // Attempt graceful shutdown with SIGTERM first - bs.proc.Process.Signal(syscall.SIGTERM) - - select { - case err := <-bs.exit: - bs.proc = nil - return err - - case <-time.After(10 * time.Second): - bs.proc.Process.Kill() - bs.proc = nil - return <-bs.exit - } -} diff --git a/go/test/endtoend/recovery/pitr/shardedpitr_test.go b/go/test/endtoend/recovery/pitr/shardedpitr_test.go deleted file mode 100644 index f2a76662918..00000000000 --- a/go/test/endtoend/recovery/pitr/shardedpitr_test.go +++ /dev/null @@ -1,603 +0,0 @@ -/* -Copyright 2020 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 pitr - -import ( - "context" - "fmt" - "os" - "os/exec" - "path" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/constants/sidecar" - "vitess.io/vitess/go/json2" - "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" - "vitess.io/vitess/go/test/endtoend/utils" - "vitess.io/vitess/go/vt/log" - - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" -) - -var ( - createTable = `create table product (id bigint(20) primary key, name char(10), created bigint(20));` - insertTable = `insert into product (id, name, created) values(%d, '%s', unix_timestamp());` - getCountID = `select count(*) from product` -) - -var ( - clusterInstance *cluster.LocalProcessCluster - - primary *cluster.Vttablet - replica1 *cluster.Vttablet - replica2 *cluster.Vttablet - shard0Primary *cluster.Vttablet - shard0Replica1 *cluster.Vttablet - shard0Replica2 *cluster.Vttablet - shard1Primary *cluster.Vttablet - shard1Replica1 *cluster.Vttablet - shard1Replica2 *cluster.Vttablet - - cell = "zone1" - hostname = "localhost" - binlogHost = "127.0.0.1" - keyspaceName = "ks" - restoreKS1Name = "restoreks1" - restoreKS2Name = "restoreks2" - restoreKS3Name = "restoreks3" - shardName = "0" - shard0Name = "-80" - shard1Name = "80-" - dbName = "vt_ks" - mysqlUserName = "vt_dba" - mysqlPassword = "VtDbaPass" - dbCredentialFile = "" - initDBFileWithPassword = "" - vSchema = `{ - "sharded": true, - "vindexes": { - "hash_index": { - "type": "hash" - } - }, - "tables": { - "product": { - "column_vindexes": [ - { - "column": "id", - "name": "hash_index" - } - ] - } - } - }` - commonTabletArg = []string{ - "--vreplication_retry_delay", "1s", - "--degraded_threshold", "5s", - "--lock_tables_timeout", "5s", - "--watch_replication_stream", - "--serving_state_grace_period", "1s"} - - defaultTimeout = 30 * time.Second - defaultTick = 1 * time.Second -) - -// Test pitr (Point in time recovery). -// ------------------------------------------- -// The following test will: -// - create a shard with primary and replica -// - run InitShardPrimary -// - point binlog server to primary -// - insert some data using vtgate (e.g. here we have inserted rows 1,2) -// - verify the replication -// - take backup of replica -// - insert some data using vtgate (e.g. we inserted rows 3 4 5 6), while inserting row-4, note down the time (restoreTime1) -// - perform a resharding to create 2 shards (-80, 80-), and delete the old shard -// - point binlog server to primary of both shards -// - insert some data using vtgate (e.g. we will insert 7 8 9 10) and verify we get required number of rows in -80, 80- shard -// - take backup of both shards -// - insert some more data using vtgate (e.g. we will insert 11 12 13 14 15), while inserting row-13, note down the time (restoreTime2) -// - note down the current time (restoreTime3) - -// - Till now we did all the presetup for assertions - -// - asserting that restoring to restoreTime1 (going from 2 shards to 1 shard) is working, i.e. we should get 4 rows. -// - asserting that while restoring if we give small timeout value, it will restore upto to the last available backup (asserting only -80 shard) -// - asserting that restoring to restoreTime2 (going from 2 shards to 2 shards with past time) is working, it will assert for both shards -// - asserting that restoring to restoreTime3 is working, we should get complete data after restoring, as we have in existing shards. -func TestPITRRecovery(t *testing.T) { - defer cluster.PanicHandler(nil) - initializeCluster(t) - defer clusterInstance.Teardown() - - // start the binlog server and point it to primary - bs := startBinlogServer(t, primary) - defer bs.stop() - - // Creating the table - _, err := primary.VttabletProcess.QueryTablet(createTable, keyspaceName, true) - require.NoError(t, err) - - insertRow(t, 1, "prd-1", false) - insertRow(t, 2, "prd-2", false) - - cluster.VerifyRowsInTabletForTable(t, replica1, keyspaceName, 2, "product") - - // backup the replica - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Backup", replica1.Alias) - require.NoError(t, err) - - // check that the backup shows up in the listing - output, err := clusterInstance.ListBackups("ks/0") - require.NoError(t, err) - assert.Equal(t, 1, len(output)) - - // now insert some more data to simulate the changes after regular backup - // every insert has some time lag/difference to simulate the time gap between rows - // and when we recover to certain time, this time gap will be able to identify the exact eligible row - var restoreTime1 string - for counter := 3; counter <= 6; counter++ { - if counter == 4 { // we want to recovery till this, so noting the time - tm := time.Now().Add(1 * time.Second).UTC() - restoreTime1 = tm.Format(time.RFC3339) - } - insertRow(t, counter, fmt.Sprintf("prd-%d", counter), true) - } - - // starting resharding process - performResharding(t) - - // start the binlog server and point it to shard0Primary - bs0 := startBinlogServer(t, shard0Primary) - defer bs0.stop() - - // start the binlog server and point it to shard1Primary - bs1 := startBinlogServer(t, shard1Primary) - defer bs1.stop() - - for counter := 7; counter <= 10; counter++ { - insertRow(t, counter, fmt.Sprintf("prd-%d", counter), false) - } - - // wait till all the shards have required data - cluster.VerifyRowsInTabletForTable(t, shard0Replica1, keyspaceName, 6, "product") - cluster.VerifyRowsInTabletForTable(t, shard1Replica1, keyspaceName, 4, "product") - - // take the backup (to simulate the regular backup) - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Backup", shard0Replica1.Alias) - require.NoError(t, err) - // take the backup (to simulate the regular backup) - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Backup", shard1Replica1.Alias) - require.NoError(t, err) - - backups, err := clusterInstance.ListBackups(keyspaceName + "/-80") - require.NoError(t, err) - require.Equal(t, len(backups), 1) - - backups, err = clusterInstance.ListBackups(keyspaceName + "/80-") - require.NoError(t, err) - require.Equal(t, len(backups), 1) - - // now insert some more data to simulate the changes after regular backup - // every insert has some time lag/difference to simulate the time gap between rows - // and when we recover to certain time, this time gap will be able to identify the exact eligible row - var restoreTime2 string - for counter := 11; counter <= 15; counter++ { - if counter == 13 { // we want to recovery till this, so noting the time - tm := time.Now().Add(1 * time.Second).UTC() - restoreTime2 = tm.Format(time.RFC3339) - } - insertRow(t, counter, fmt.Sprintf("prd-%d", counter), true) - } - restoreTime3 := time.Now().UTC().Format(time.RFC3339) - - // creating restore keyspace with snapshot time as restoreTime1 - createRestoreKeyspace(t, restoreTime1, restoreKS1Name) - - // Launching a recovery tablet which recovers data from the primary till the restoreTime1 - testTabletRecovery(t, bs, "2m", restoreKS1Name, "0", "INT64(4)") - - // create restoreKeyspace with snapshot time as restoreTime2 - createRestoreKeyspace(t, restoreTime2, restoreKS2Name) - - // test the recovery with smaller binlog_lookup_timeout for shard0 - // since we have small lookup timeout, it will just get whatever available in the backup - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 1 | prd-1 | 1597219030 | - // | 2 | prd-2 | 1597219030 | - // | 3 | prd-3 | 1597219043 | - // | 5 | prd-5 | 1597219045 | - // | 9 | prd-9 | 1597219130 | - // | 10 | prd-10 | 1597219130 | - // +----+--------+------------+ - testTabletRecovery(t, bs0, "1ms", restoreKS2Name, "-80", "INT64(6)") - - // test the recovery with valid binlog_lookup_timeout for shard0 and getting the data till the restoreTime2 - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 1 | prd-1 | 1597219030 | - // | 2 | prd-2 | 1597219030 | - // | 3 | prd-3 | 1597219043 | - // | 5 | prd-5 | 1597219045 | - // | 9 | prd-9 | 1597219130 | - // | 10 | prd-10 | 1597219130 | - // | 13 | prd-13 | 1597219141 | - // +----+--------+------------+ - testTabletRecovery(t, bs0, "2m", restoreKS2Name, "-80", "INT64(7)") - - // test the recovery with valid binlog_lookup_timeout for shard1 and getting the data till the restoreTime2 - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 4 | prd-4 | 1597219044 | - // | 6 | prd-6 | 1597219046 | - // | 7 | prd-7 | 1597219130 | - // | 8 | prd-8 | 1597219130 | - // | 11 | prd-11 | 1597219139 | - // | 12 | prd-12 | 1597219140 | - // +----+--------+------------+ - testTabletRecovery(t, bs1, "2m", restoreKS2Name, "80-", "INT64(6)") - - // test the recovery with timetorecover > (timestmap of last binlog event in binlog server) - createRestoreKeyspace(t, restoreTime3, restoreKS3Name) - - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 1 | prd-1 | 1597219030 | - // | 2 | prd-2 | 1597219030 | - // | 3 | prd-3 | 1597219043 | - // | 5 | prd-5 | 1597219045 | - // | 9 | prd-9 | 1597219130 | - // | 10 | prd-10 | 1597219130 | - // | 13 | prd-13 | 1597219141 | - // | 15 | prd-15 | 1597219142 | - // +----+--------+------------+ - testTabletRecovery(t, bs0, "2m", restoreKS3Name, "-80", "INT64(8)") - - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 4 | prd-4 | 1597219044 | - // | 6 | prd-6 | 1597219046 | - // | 7 | prd-7 | 1597219130 | - // | 8 | prd-8 | 1597219130 | - // | 11 | prd-11 | 1597219139 | - // | 12 | prd-12 | 1597219140 | - // | 14 | prd-14 | 1597219142 | - // +----+--------+------------+ - testTabletRecovery(t, bs1, "2m", restoreKS3Name, "80-", "INT64(7)") -} - -func performResharding(t *testing.T) { - err := clusterInstance.VtctldClientProcess.ApplyVSchema(keyspaceName, vSchema) - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "create", "--source-shards=0", "--target-shards=-80,80-", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - waitTimeout := 30 * time.Second - shard0Primary.VttabletProcess.WaitForVReplicationToCatchup(t, "ks.reshardWorkflow", dbName, sidecar.DefaultName, waitTimeout) - shard1Primary.VttabletProcess.WaitForVReplicationToCatchup(t, "ks.reshardWorkflow", dbName, sidecar.DefaultName, waitTimeout) - - waitForNoWorkflowLag(t, clusterInstance, "ks", "reshardWorkflow") - - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "SwitchTraffic", "--tablet-types=rdonly", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "SwitchTraffic", "--tablet-types=replica", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - // then serve primary from the split shards - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "SwitchTraffic", "--tablet-types=primary", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - // remove the original tablets in the original shard - removeTablets(t, []*cluster.Vttablet{primary, replica1, replica2}) - - for _, tablet := range []*cluster.Vttablet{replica1, replica2} { - err = clusterInstance.VtctldClientProcess.ExecuteCommand("DeleteTablets", tablet.Alias) - require.NoError(t, err) - } - err = clusterInstance.VtctldClientProcess.ExecuteCommand("DeleteTablets", "--allow-primary", primary.Alias) - require.NoError(t, err) - - // rebuild the serving graph, all mentions of the old shards should be gone - err = clusterInstance.VtctldClientProcess.ExecuteCommand("RebuildKeyspaceGraph", "ks") - require.NoError(t, err) - - // delete the original shard - err = clusterInstance.VtctldClientProcess.ExecuteCommand("DeleteShards", "ks/0") - require.NoError(t, err) - - // Restart vtgate process - err = clusterInstance.VtgateProcess.TearDown() - require.NoError(t, err) - - err = clusterInstance.VtgateProcess.Setup() - require.NoError(t, err) - - clusterInstance.WaitForTabletsToHealthyInVtgate() -} - -func startBinlogServer(t *testing.T, primaryTablet *cluster.Vttablet) *binLogServer { - bs, err := newBinlogServer(hostname, clusterInstance.GetAndReservePort()) - require.NoError(t, err) - - err = bs.start(mysqlSource{ - hostname: binlogHost, - port: primaryTablet.MysqlctlProcess.MySQLPort, - username: mysqlUserName, - password: mysqlPassword, - }) - require.NoError(t, err) - return bs -} - -func removeTablets(t *testing.T, tablets []*cluster.Vttablet) { - var mysqlProcs []*exec.Cmd - for _, tablet := range tablets { - proc, _ := tablet.MysqlctlProcess.StopProcess() - mysqlProcs = append(mysqlProcs, proc) - } - for _, proc := range mysqlProcs { - err := proc.Wait() - require.NoError(t, err) - } - for _, tablet := range tablets { - tablet.VttabletProcess.TearDown() - } -} - -func initializeCluster(t *testing.T) { - clusterInstance = cluster.NewCluster(cell, hostname) - - // Start topo server - err := clusterInstance.StartTopo() - require.NoError(t, err) - - // Start keyspace - keyspace := &cluster.Keyspace{ - Name: keyspaceName, - } - clusterInstance.Keyspaces = append(clusterInstance.Keyspaces, *keyspace) - - shard := &cluster.Shard{ - Name: shardName, - } - shard0 := &cluster.Shard{ - Name: shard0Name, - } - shard1 := &cluster.Shard{ - Name: shard1Name, - } - - // Defining all the tablets - primary = clusterInstance.NewVttabletInstance("replica", 0, "") - replica1 = clusterInstance.NewVttabletInstance("replica", 0, "") - replica2 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard0Primary = clusterInstance.NewVttabletInstance("replica", 0, "") - shard0Replica1 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard0Replica2 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard1Primary = clusterInstance.NewVttabletInstance("replica", 0, "") - shard1Replica1 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard1Replica2 = clusterInstance.NewVttabletInstance("replica", 0, "") - - shard.Vttablets = []*cluster.Vttablet{primary, replica1, replica2} - shard0.Vttablets = []*cluster.Vttablet{shard0Primary, shard0Replica1, shard0Replica2} - shard1.Vttablets = []*cluster.Vttablet{shard1Primary, shard1Replica1, shard1Replica2} - - dbCredentialFile = cluster.WriteDbCredentialToTmp(clusterInstance.TmpDirectory) - extraArgs := []string{"--db-credentials-file", dbCredentialFile} - commonTabletArg = append(commonTabletArg, "--db-credentials-file", dbCredentialFile) - - clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, commonTabletArg...) - clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, "--restore_from_backup") - - err = clusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard, *shard0, *shard1}) - require.NoError(t, err) - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) - out, err := vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync") - require.NoError(t, err, out) - - initDb, _ := os.ReadFile(path.Join(os.Getenv("VTROOT"), "/config/init_db.sql")) - sql := string(initDb) - // The original init_db.sql does not have any passwords. Here we update the init file with passwords - sql, err = utils.GetInitDBSQL(sql, cluster.GetPasswordUpdateSQL(clusterInstance), "") - require.NoError(t, err, "expected to load init_db file") - initDBFileWithPassword = path.Join(clusterInstance.TmpDirectory, "init_db_with_passwords.sql") - err = os.WriteFile(initDBFileWithPassword, []byte(sql), 0660) - require.NoError(t, err, "expected to load init_db file") - - // Start MySql - var mysqlCtlProcessList []*exec.Cmd - for _, shard := range clusterInstance.Keyspaces[0].Shards { - for _, tablet := range shard.Vttablets { - tablet.MysqlctlProcess.InitDBFile = initDBFileWithPassword - tablet.VttabletProcess.DbPassword = mysqlPassword - tablet.MysqlctlProcess.ExtraArgs = extraArgs - proc, err := tablet.MysqlctlProcess.StartProcess() - require.NoError(t, err) - mysqlCtlProcessList = append(mysqlCtlProcessList, proc) - } - } - - // Wait for mysql processes to start - for _, proc := range mysqlCtlProcessList { - err = proc.Wait() - require.NoError(t, err) - } - - for _, shard := range clusterInstance.Keyspaces[0].Shards { - for _, tablet := range shard.Vttablets { - err = tablet.VttabletProcess.Setup() - require.NoError(t, err) - } - } - - err = clusterInstance.VtctldClientProcess.InitShardPrimary(keyspaceName, shard.Name, cell, primary.TabletUID) - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.InitShardPrimary(keyspaceName, shard0.Name, cell, shard0Primary.TabletUID) - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.InitShardPrimary(keyspaceName, shard1.Name, cell, shard1Primary.TabletUID) - require.NoError(t, err) - - err = clusterInstance.StartVTOrc(keyspaceName) - require.NoError(t, err) - - // Start vtgate - err = clusterInstance.StartVtgate() - require.NoError(t, err) -} - -func insertRow(t *testing.T, id int, productName string, isSlow bool) { - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: clusterInstance.Hostname, - Port: clusterInstance.VtgateMySQLPort, - } - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - - insertSmt := fmt.Sprintf(insertTable, id, productName) - _, err = conn.ExecuteFetch(insertSmt, 1000, true) - require.NoError(t, err) - - if isSlow { - time.Sleep(1 * time.Second) - } -} - -func createRestoreKeyspace(t *testing.T, timeToRecover, restoreKeyspaceName string) { - output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", - "--type=SNAPSHOT", "--base-keyspace="+keyspaceName, - "--snapshot-timestamp", timeToRecover, restoreKeyspaceName) - log.Info(output) - require.NoError(t, err) -} - -func testTabletRecovery(t *testing.T, binlogServer *binLogServer, lookupTimeout, restoreKeyspaceName, shardName, expectedRows string) { - recoveryTablet := clusterInstance.NewVttabletInstance("replica", 0, cell) - launchRecoveryTablet(t, recoveryTablet, binlogServer, lookupTimeout, restoreKeyspaceName, shardName) - - sqlRes, err := recoveryTablet.VttabletProcess.QueryTablet(getCountID, keyspaceName, true) - require.NoError(t, err) - assert.Equal(t, expectedRows, sqlRes.Rows[0][0].String()) - - defer recoveryTablet.MysqlctlProcess.Stop() - defer recoveryTablet.VttabletProcess.TearDown() -} - -func launchRecoveryTablet(t *testing.T, tablet *cluster.Vttablet, binlogServer *binLogServer, lookupTimeout, restoreKeyspaceName, shardName string) { - mysqlctlProcess, err := cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, clusterInstance.TmpDirectory) - require.NoError(t, err) - tablet.MysqlctlProcess = *mysqlctlProcess - extraArgs := []string{"--db-credentials-file", dbCredentialFile} - tablet.MysqlctlProcess.InitDBFile = initDBFileWithPassword - tablet.VttabletProcess.DbPassword = mysqlPassword - tablet.MysqlctlProcess.ExtraArgs = extraArgs - err = tablet.MysqlctlProcess.Start() - require.NoError(t, err) - - tablet.VttabletProcess = cluster.VttabletProcessInstance( - tablet.HTTPPort, - tablet.GrpcPort, - tablet.TabletUID, - clusterInstance.Cell, - shardName, - keyspaceName, - clusterInstance.VtctldProcess.Port, - tablet.Type, - clusterInstance.TopoProcess.Port, - clusterInstance.Hostname, - clusterInstance.TmpDirectory, - clusterInstance.VtTabletExtraArgs, - clusterInstance.DefaultCharset) - tablet.Alias = tablet.VttabletProcess.TabletPath - tablet.VttabletProcess.SupportsBackup = true - tablet.VttabletProcess.Keyspace = restoreKeyspaceName - tablet.VttabletProcess.ExtraArgs = []string{ - "--disable_active_reparents", - "--enable_replication_reporter=false", - "--init_db_name_override", dbName, - "--init_tablet_type", "replica", - "--init_keyspace", restoreKeyspaceName, - "--init_shard", shardName, - "--binlog_host", binlogServer.hostname, - "--binlog_port", fmt.Sprintf("%d", binlogServer.port), - "--binlog_user", binlogServer.username, - "--binlog_password", binlogServer.password, - "--pitr_gtid_lookup_timeout", lookupTimeout, - "--vreplication_retry_delay", "1s", - "--degraded_threshold", "5s", - "--lock_tables_timeout", "5s", - "--watch_replication_stream", - "--serving_state_grace_period", "1s", - "--db-credentials-file", dbCredentialFile, - } - tablet.VttabletProcess.ServingStatus = "" - - err = tablet.VttabletProcess.Setup() - require.NoError(t, err) - - tablet.VttabletProcess.WaitForTabletStatusesForTimeout([]string{"SERVING"}, 20*time.Second) -} - -// waitForNoWorkflowLag waits for the VReplication workflow's MaxVReplicationTransactionLag -// value to be 0. -func waitForNoWorkflowLag(t *testing.T, vc *cluster.LocalProcessCluster, ks string, workflow string) { - var lag int64 - timer := time.NewTimer(defaultTimeout) - defer timer.Stop() - for { - output, err := vc.VtctldClientProcess.ExecuteCommandWithOutput("Workflow", "--keyspace", ks, "show", "--workflow", workflow) - require.NoError(t, err) - - var resp vtctldatapb.GetWorkflowsResponse - err = json2.UnmarshalPB([]byte(output), &resp) - require.NoError(t, err) - require.GreaterOrEqual(t, len(resp.Workflows), 1, "responce should have at least one workflow") - lag = resp.Workflows[0].MaxVReplicationTransactionLag - if lag == 0 { - return - } - select { - case <-timer.C: - require.FailNow(t, fmt.Sprintf("workflow %q did not eliminate VReplication lag before the timeout of %s; last seen MaxVReplicationTransactionLag: %d", - strings.Join([]string{ks, workflow}, "."), defaultTimeout, lag)) - default: - time.Sleep(defaultTick) - } - } -} diff --git a/go/test/endtoend/recovery/recovery_util.go b/go/test/endtoend/recovery/recovery_util.go index cffae6a5005..f862b30a9b3 100644 --- a/go/test/endtoend/recovery/recovery_util.go +++ b/go/test/endtoend/recovery/recovery_util.go @@ -55,16 +55,16 @@ func RestoreTablet(t *testing.T, localCluster *cluster.LocalProcessCluster, tabl tablet.ValidateTabletRestart(t) replicaTabletArgs := commonTabletArg - _, err := localCluster.VtctlProcess.ExecuteCommandWithOutput("GetKeyspace", restoreKSName) + _, err := localCluster.VtctldClientProcess.ExecuteCommandWithOutput("GetKeyspace", restoreKSName) if restoreTime.IsZero() { restoreTime = time.Now().UTC() } if err != nil { - _, err := localCluster.VtctlProcess.ExecuteCommandWithOutput("CreateKeyspace", "--", - "--keyspace_type=SNAPSHOT", "--base_keyspace="+keyspaceName, - "--snapshot_time", restoreTime.Format(time.RFC3339), restoreKSName) + _, err := localCluster.VtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", restoreKSName, + "--type=SNAPSHOT", "--base-keyspace="+keyspaceName, + "--snapshot-timestamp", restoreTime.Format(time.RFC3339)) require.Nil(t, err) } diff --git a/go/test/endtoend/recovery/unshardedrecovery/recovery.go b/go/test/endtoend/recovery/unshardedrecovery/recovery.go index 1ebb7c2647f..0d3c38a50f7 100644 --- a/go/test/endtoend/recovery/unshardedrecovery/recovery.go +++ b/go/test/endtoend/recovery/unshardedrecovery/recovery.go @@ -72,7 +72,6 @@ var ( // TestMainImpl creates cluster for unsharded recovery testing. func TestMainImpl(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode, err := func() (int, error) { @@ -159,7 +158,7 @@ func TestMainImpl(m *testing.M) { } } - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", localCluster.VtctldProcess.GrpcPort, localCluster.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(localCluster.VtctldProcess.GrpcPort, localCluster.TopoPort, "localhost", localCluster.TmpDirectory) _, err = vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync") if err != nil { return 1, err @@ -201,7 +200,6 @@ func TestMainImpl(m *testing.M) { // // 7. check that vtgate queries work correctly func TestRecoveryImpl(t *testing.T) { - defer cluster.PanicHandler(t) defer tabletsTeardown() verifyInitialReplication(t) diff --git a/go/test/endtoend/reparent/emergencyreparent/ers_test.go b/go/test/endtoend/reparent/emergencyreparent/ers_test.go index 584bccfdfb7..f2febf9e27f 100644 --- a/go/test/endtoend/reparent/emergencyreparent/ers_test.go +++ b/go/test/endtoend/reparent/emergencyreparent/ers_test.go @@ -28,11 +28,11 @@ import ( "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/reparent/utils" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) func TestTrivialERS(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -48,16 +48,15 @@ func TestTrivialERS(t *testing.T) { } // We should do the same for vtctl binary for i := 1; i <= 4; i++ { - out, err := utils.ErsWithVtctl(clusterInstance) - log.Infof("ERS-vtctl loop %d. EmergencyReparentShard Output: %v", i, out) + out, err := utils.ErsWithVtctldClient(clusterInstance) + log.Infof("ERS-vtctldclient loop %d. EmergencyReparentShard Output: %v", i, out) require.NoError(t, err) time.Sleep(5 * time.Second) } } func TestReparentIgnoreReplicas(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets var err error @@ -98,8 +97,7 @@ func TestReparentIgnoreReplicas(t *testing.T) { } func TestReparentDownPrimary(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -134,8 +132,7 @@ func TestReparentDownPrimary(t *testing.T) { } func TestReparentNoChoiceDownPrimary(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets var err error @@ -170,8 +167,7 @@ func TestReparentNoChoiceDownPrimary(t *testing.T) { func TestSemiSyncSetupCorrectly(t *testing.T) { t.Run("semi-sync enabled", func(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -198,8 +194,7 @@ func TestSemiSyncSetupCorrectly(t *testing.T) { }) t.Run("semi-sync disabled", func(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "none") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilityNone) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -228,8 +223,7 @@ func TestSemiSyncSetupCorrectly(t *testing.T) { // TestERSPromoteRdonly tests that we never end up promoting a rdonly instance as the primary func TestERSPromoteRdonly(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets var err error @@ -256,8 +250,7 @@ func TestERSPromoteRdonly(t *testing.T) { // TestERSPreventCrossCellPromotion tests that we promote a replica in the same cell as the previous primary if prevent cross cell promotion flag is set func TestERSPreventCrossCellPromotion(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets var err error @@ -279,8 +272,7 @@ func TestERSPreventCrossCellPromotion(t *testing.T) { // TestPullFromRdonly tests that if a rdonly tablet is the most advanced, then our promoted primary should have // caught up to it by pulling transactions from it func TestPullFromRdonly(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets var err error @@ -351,8 +343,7 @@ func TestPullFromRdonly(t *testing.T) { // replicas which do not have any replication status and also succeeds if the io thread // is stopped on the primary elect. func TestNoReplicationStatusAndIOThreadStopped(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]}) @@ -405,7 +396,7 @@ func TestERSForInitialization(t *testing.T) { err = clusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard}) require.NoError(t, err) if clusterInstance.VtctlMajorVersion >= 14 { - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TopoPort, "localhost", clusterInstance.TmpDirectory) out, err := vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspace.Name, "--durability-policy=semi_sync") require.NoError(t, err, out) } @@ -451,8 +442,7 @@ func TestERSForInitialization(t *testing.T) { } func TestRecoverWithMultipleFailures(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]}) @@ -479,8 +469,7 @@ func TestRecoverWithMultipleFailures(t *testing.T) { // TestERSFailFast tests that ERS will fail fast if it cannot find any tablet which can be safely promoted instead of promoting // a tablet and hanging while inserting a row in the reparent journal on getting semi-sync ACKs func TestERSFailFast(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]}) @@ -519,8 +508,7 @@ func TestERSFailFast(t *testing.T) { // TestReplicationStopped checks that ERS ignores the tablets that have sql thread stopped. // If there are more than 1, we also fail. func TestReplicationStopped(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]}) diff --git a/go/test/endtoend/reparent/newfeaturetest/reparent_test.go b/go/test/endtoend/reparent/newfeaturetest/reparent_test.go index b6f34af7294..fc5db965847 100644 --- a/go/test/endtoend/reparent/newfeaturetest/reparent_test.go +++ b/go/test/endtoend/reparent/newfeaturetest/reparent_test.go @@ -28,6 +28,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/reparent/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) // TestRecoverWithMultipleVttabletFailures tests that ERS succeeds with the default values @@ -36,8 +37,7 @@ import ( // The test takes down the vttablets of the primary and a rdonly tablet and runs ERS with the // default values of remote_operation_timeout, lock-timeout flags and wait_replicas_timeout subflag. func TestRecoverWithMultipleVttabletFailures(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]}) @@ -68,8 +68,7 @@ func TestRecoverWithMultipleVttabletFailures(t *testing.T) { // and ERS succeeds. func TestSingleReplicaERS(t *testing.T) { // Set up a cluster with none durability policy - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "none") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilityNone) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets // Confirm that the replication is setup correctly in the beginning. @@ -104,8 +103,7 @@ func TestSingleReplicaERS(t *testing.T) { // TestTabletRestart tests that a running tablet can be restarted and everything is still fine func TestTabletRestart(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -117,8 +115,7 @@ func TestTabletRestart(t *testing.T) { // Tests ensures that ChangeTabletType works even when semi-sync plugins are not loaded. func TestChangeTypeWithoutSemiSync(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "none") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilityNone) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -163,8 +160,7 @@ func TestChangeTypeWithoutSemiSync(t *testing.T) { // TestERSWithWriteInPromoteReplica tests that ERS doesn't fail even if there is a // write that happens when PromoteReplica is called. func TestERSWithWriteInPromoteReplica(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]}) @@ -181,8 +177,7 @@ func TestERSWithWriteInPromoteReplica(t *testing.T) { } func TestBufferingWithMultipleDisruptions(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupShardedReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupShardedReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) // Stop all VTOrc instances, so that they don't interfere with the test. diff --git a/go/test/endtoend/reparent/plannedreparent/reparent_range_based_test.go b/go/test/endtoend/reparent/plannedreparent/reparent_range_based_test.go index 2d89893569d..91471b1cebb 100644 --- a/go/test/endtoend/reparent/plannedreparent/reparent_range_based_test.go +++ b/go/test/endtoend/reparent/plannedreparent/reparent_range_based_test.go @@ -28,7 +28,6 @@ import ( ) func TestReparentGracefulRangeBased(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() utils.ShardName = "0000000000000000-ffffffffffffffff" diff --git a/go/test/endtoend/reparent/plannedreparent/reparent_test.go b/go/test/endtoend/reparent/plannedreparent/reparent_test.go index d3907b0bc5b..7b750dc3f16 100644 --- a/go/test/endtoend/reparent/plannedreparent/reparent_test.go +++ b/go/test/endtoend/reparent/plannedreparent/reparent_test.go @@ -33,11 +33,11 @@ import ( "vitess.io/vitess/go/test/endtoend/reparent/utils" "vitess.io/vitess/go/vt/log" replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) func TestPrimaryToSpareStateChangeImpossible(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -48,8 +48,7 @@ func TestPrimaryToSpareStateChangeImpossible(t *testing.T) { } func TestReparentCrossCell(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -62,8 +61,7 @@ func TestReparentCrossCell(t *testing.T) { } func TestReparentGraceful(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -85,8 +83,7 @@ func TestReparentGraceful(t *testing.T) { // TestPRSWithDrainedLaggingTablet tests that PRS succeeds even if we have a lagging drained tablet func TestPRSWithDrainedLaggingTablet(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -112,8 +109,7 @@ func TestPRSWithDrainedLaggingTablet(t *testing.T) { } func TestReparentReplicaOffline(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -130,8 +126,7 @@ func TestReparentReplicaOffline(t *testing.T) { } func TestReparentAvoid(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.DeleteTablet(t, clusterInstance, tablets[2]) @@ -178,15 +173,13 @@ func TestReparentAvoid(t *testing.T) { } func TestReparentFromOutside(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) reparentFromOutside(t, clusterInstance, false) } func TestReparentFromOutsideWithNoPrimary(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -285,8 +278,7 @@ func reparentFromOutside(t *testing.T, clusterInstance *cluster.LocalProcessClus } func TestReparentWithDownReplica(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -332,8 +324,7 @@ func TestReparentWithDownReplica(t *testing.T) { } func TestChangeTypeSemiSync(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -399,8 +390,7 @@ func TestChangeTypeSemiSync(t *testing.T) { // 1. When PRS is run with the cross_cell durability policy setup, then the semi-sync settings on all the tablets are as expected // 2. Bringing up a new vttablet should have its replication and semi-sync setup correctly without any manual intervention func TestCrossCellDurability(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "cross_cell") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilityCrossCell) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets @@ -439,8 +429,7 @@ func TestCrossCellDurability(t *testing.T) { // TestFullStatus tests that the RPC FullStatus works as intended. func TestFullStatus(t *testing.T) { - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]}) diff --git a/go/test/endtoend/reparent/prscomplex/main_test.go b/go/test/endtoend/reparent/prscomplex/main_test.go index 88e3d6c09fa..c2dafb8589f 100644 --- a/go/test/endtoend/reparent/prscomplex/main_test.go +++ b/go/test/endtoend/reparent/prscomplex/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/reparent/prssettingspool/main_test.go b/go/test/endtoend/reparent/prssettingspool/main_test.go index 4364836841b..c6b59fd6372 100644 --- a/go/test/endtoend/reparent/prssettingspool/main_test.go +++ b/go/test/endtoend/reparent/prssettingspool/main_test.go @@ -43,7 +43,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/reparent/semisync/semi_sync_test.go b/go/test/endtoend/reparent/semisync/semi_sync_test.go index 07cf4a7abc8..804a1645f19 100644 --- a/go/test/endtoend/reparent/semisync/semi_sync_test.go +++ b/go/test/endtoend/reparent/semisync/semi_sync_test.go @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/reparent/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) func TestSemiSyncUpgradeDowngrade(t *testing.T) { @@ -33,8 +34,7 @@ func TestSemiSyncUpgradeDowngrade(t *testing.T) { if ver != 21 { t.Skip("We only want to run this test for v21 release") } - defer cluster.PanicHandler(t) - clusterInstance := utils.SetupReparentCluster(t, "semi_sync") + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets diff --git a/go/test/endtoend/reparent/utils/utils.go b/go/test/endtoend/reparent/utils/utils.go index 2a51262557b..521e17606ce 100644 --- a/go/test/endtoend/reparent/utils/utils.go +++ b/go/test/endtoend/reparent/utils/utils.go @@ -32,6 +32,7 @@ import ( "github.com/stretchr/testify/require" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vttablet/tabletconn" "vitess.io/vitess/go/mysql" @@ -71,7 +72,7 @@ func SetupReparentCluster(t *testing.T, durability string) *cluster.LocalProcess // SetupRangeBasedCluster sets up the range based cluster func SetupRangeBasedCluster(ctx context.Context, t *testing.T) *cluster.LocalProcessCluster { - return setupCluster(ctx, t, ShardName, []string{cell1}, []int{2}, "semi_sync") + return setupCluster(ctx, t, ShardName, []string{cell1}, []int{2}, policy.DurabilitySemiSync) } // SetupShardedReparentCluster is used to setup a sharded cluster for testing @@ -154,7 +155,7 @@ func setupCluster(ctx context.Context, t *testing.T, shardName string, cells []s require.NoError(t, err, "Error managing topo") numCell := 1 for numCell < len(cells) { - err = clusterInstance.VtctlProcess.AddCellInfo(cells[numCell]) + err = clusterInstance.VtctldClientProcess.AddCellInfo(cells[numCell]) require.NoError(t, err, "Error managing topo") numCell++ } @@ -208,7 +209,7 @@ func setupCluster(ctx context.Context, t *testing.T, shardName string, cells []s } } if clusterInstance.VtctlMajorVersion >= 14 { - clusterInstance.VtctldClientProcess = *cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) + clusterInstance.VtctldClientProcess = *cluster.VtctldClientProcessInstance(clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TopoPort, "localhost", clusterInstance.TmpDirectory) out, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", KeyspaceName, fmt.Sprintf("--durability-policy=%s", durability)) require.NoError(t, err, out) } @@ -406,10 +407,10 @@ func ErsIgnoreTablet(clusterInstance *cluster.LocalProcessCluster, tab *cluster. return clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput(args...) } -// ErsWithVtctl runs ERS via vtctl binary -func ErsWithVtctl(clusterInstance *cluster.LocalProcessCluster) (string, error) { - args := []string{"EmergencyReparentShard", "--", "--keyspace_shard", fmt.Sprintf("%s/%s", KeyspaceName, ShardName)} - return clusterInstance.VtctlProcess.ExecuteCommandWithOutput(args...) +// ErsWithVtctldClient runs ERS via a vtctldclient binary. +func ErsWithVtctldClient(clusterInstance *cluster.LocalProcessCluster) (string, error) { + args := []string{"EmergencyReparentShard", fmt.Sprintf("%s/%s", KeyspaceName, ShardName)} + return clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput(args...) } // endregion @@ -677,7 +678,7 @@ func CheckReparentFromOutside(t *testing.T, clusterInstance *cluster.LocalProces assert.Len(t, result[cell1].Nodes, 2) } } else { - result, err := clusterInstance.VtctlclientProcess.ExecuteCommandWithOutput("GetShardReplication", cell1, KeyspaceShard) + result, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("GetShardReplication", cell1, KeyspaceShard) require.Nil(t, err, "error should be Nil") if !downPrimary { assertNodeCount(t, result, int(3)) diff --git a/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go b/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go index b4ecb367e8b..c850e22945c 100644 --- a/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go +++ b/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go @@ -68,7 +68,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -132,7 +131,6 @@ func TestMain(m *testing.M) { } func TestSchemadiffSchemaChanges(t *testing.T) { - defer cluster.PanicHandler(t) shards := clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) @@ -275,7 +273,6 @@ func testSingle(t *testing.T, testName string) { } // func TestRandomSchemaChanges(t *testing.T) { -// defer cluster.PanicHandler(t) // hints := &schemadiff.DiffHints{AutoIncrementStrategy: schemadiff.AutoIncrementIgnore} // // count := 20 diff --git a/go/test/endtoend/sharded/sharded_keyspace_test.go b/go/test/endtoend/sharded/sharded_keyspace_test.go index 192355fa6ef..1170609f62e 100644 --- a/go/test/endtoend/sharded/sharded_keyspace_test.go +++ b/go/test/endtoend/sharded/sharded_keyspace_test.go @@ -73,7 +73,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -84,7 +83,7 @@ func TestMain(m *testing.M) { if err := clusterInstance.StartTopo(); err != nil { return 1, err } - if err := clusterInstance.VtctlProcess.CreateKeyspace(keyspaceName, sidecar.DefaultName, ""); err != nil { + if err := clusterInstance.VtctldClientProcess.CreateKeyspace(keyspaceName, sidecar.DefaultName, ""); err != nil { return 1, err } @@ -102,7 +101,6 @@ func TestMain(m *testing.M) { } func TestShardedKeyspace(t *testing.T) { - defer cluster.PanicHandler(t) shard1 := clusterInstance.Keyspaces[0].Shards[0] shard2 := clusterInstance.Keyspaces[0].Shards[1] @@ -149,14 +147,14 @@ func TestShardedKeyspace(t *testing.T) { require.Nil(t, err) assert.Equal(t, `[[INT64(1) VARCHAR("test 1")]]`, fmt.Sprintf("%v", rows.Rows)) - err = clusterInstance.VtctlclientProcess.ExecuteCommand("ValidateSchemaShard", fmt.Sprintf("%s/%s", keyspaceName, shard1.Name)) + err = clusterInstance.VtctldClientProcess.ExecuteCommand("ValidateSchemaShard", fmt.Sprintf("%s/%s", keyspaceName, shard1.Name)) require.Nil(t, err) - err = clusterInstance.VtctlclientProcess.ExecuteCommand("ValidateSchemaShard", fmt.Sprintf("%s/%s", keyspaceName, shard1.Name)) + err = clusterInstance.VtctldClientProcess.ExecuteCommand("ValidateSchemaShard", fmt.Sprintf("%s/%s", keyspaceName, shard1.Name)) require.Nil(t, err) - output, err := clusterInstance.VtctlclientProcess.ExecuteCommandWithOutput("ValidateSchemaKeyspace", keyspaceName) - require.Error(t, err) + output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("ValidateSchemaKeyspace", keyspaceName) + require.NoError(t, err) // We should assert that there is a schema difference and that both the shard primaries are involved in it. // However, we cannot assert in which order the two primaries will occur since the underlying function does not guarantee that // We could have an output here like `schemas differ ... shard1Primary ... differs from: shard2Primary ...` or `schemas differ ... shard2Primary ... differs from: shard1Primary ...` @@ -168,9 +166,9 @@ func TestShardedKeyspace(t *testing.T) { require.Nil(t, err) err = clusterInstance.VtctldClientProcess.ExecuteCommand("GetPermissions", shard1.Vttablets[1].Alias) require.Nil(t, err) - err = clusterInstance.VtctlclientProcess.ExecuteCommand("ValidatePermissionsShard", fmt.Sprintf("%s/%s", keyspaceName, shard1.Name)) + err = clusterInstance.VtctldClientProcess.ExecuteCommand("ValidatePermissionsShard", fmt.Sprintf("%s/%s", keyspaceName, shard1.Name)) require.Nil(t, err) - err = clusterInstance.VtctlclientProcess.ExecuteCommand("ValidatePermissionsKeyspace", keyspaceName) + err = clusterInstance.VtctldClientProcess.ExecuteCommand("ValidatePermissionsKeyspace", keyspaceName) require.Nil(t, err) rows, err = shard1Primary.VttabletProcess.QueryTablet("select id, msg from vt_select_test order by id", keyspaceName, true) diff --git a/go/test/endtoend/stress/stress_test.go b/go/test/endtoend/stress/stress_test.go index 30a5ee69c1a..1bf716274d4 100644 --- a/go/test/endtoend/stress/stress_test.go +++ b/go/test/endtoend/stress/stress_test.go @@ -42,7 +42,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -84,7 +83,6 @@ func TestMain(m *testing.M) { // The stressor is started on its own goroutine while the end-to-end test // is executed on the same cluster. func TestSimpleStressTest(t *testing.T) { - defer cluster.PanicHandler(t) cfg := stress.DefaultConfig cfg.ConnParams = &vtParams diff --git a/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go b/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go index ca4fe5f6094..920e2193453 100644 --- a/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go +++ b/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go @@ -272,7 +272,6 @@ type BufferingTest struct { } func (bt *BufferingTest) Test(t *testing.T) { - defer cluster.PanicHandler(t) clusterInstance, exitCode := bt.createCluster() if exitCode != 0 { t.Fatal("failed to start cluster") diff --git a/go/test/endtoend/tabletgateway/main_test.go b/go/test/endtoend/tabletgateway/main_test.go index 354be6969d3..cf179c49845 100644 --- a/go/test/endtoend/tabletgateway/main_test.go +++ b/go/test/endtoend/tabletgateway/main_test.go @@ -61,7 +61,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/tabletgateway/vtgate_test.go b/go/test/endtoend/tabletgateway/vtgate_test.go index 1f4f8758e16..d9c87fdc7f3 100644 --- a/go/test/endtoend/tabletgateway/vtgate_test.go +++ b/go/test/endtoend/tabletgateway/vtgate_test.go @@ -40,7 +40,6 @@ import ( ) func TestVtgateHealthCheck(t *testing.T) { - defer cluster.PanicHandler(t) // Healthcheck interval on tablet is set to 1s, so sleep for 2s time.Sleep(2 * time.Second) verifyVtgateVariables(t, clusterInstance.VtgateProcess.VerifyURL) @@ -54,7 +53,6 @@ func TestVtgateHealthCheck(t *testing.T) { } func TestVtgateReplicationStatusCheck(t *testing.T) { - defer cluster.PanicHandler(t) // Healthcheck interval on tablet is set to 1s, so sleep for 2s time.Sleep(2 * time.Second) verifyVtgateVariables(t, clusterInstance.VtgateProcess.VerifyURL) @@ -104,7 +102,6 @@ func TestVtgateReplicationStatusCheck(t *testing.T) { } func TestVtgateReplicationStatusCheckWithTabletTypeChange(t *testing.T) { - defer cluster.PanicHandler(t) // Healthcheck interval on tablet is set to 1s, so sleep for 2s time.Sleep(2 * time.Second) verifyVtgateVariables(t, clusterInstance.VtgateProcess.VerifyURL) @@ -180,7 +177,6 @@ func retryNTimes(t *testing.T, maxRetries int, f func() bool) { func TestReplicaTransactions(t *testing.T) { // TODO(deepthi): this test seems to depend on previous test. Fix tearDown so that tests are independent - defer cluster.PanicHandler(t) // Healthcheck interval on tablet is set to 1s, so sleep for 2s time.Sleep(2 * time.Second) ctx := context.Background() @@ -287,7 +283,6 @@ func TestReplicaTransactions(t *testing.T) { // TestStreamingRPCStuck tests that StreamExecute calls don't get stuck on the vttablets if a client stop reading from a stream. func TestStreamingRPCStuck(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtConn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) diff --git a/go/test/endtoend/tabletmanager/commands_test.go b/go/test/endtoend/tabletmanager/commands_test.go index d5d946a164c..67127ab740f 100644 --- a/go/test/endtoend/tabletmanager/commands_test.go +++ b/go/test/endtoend/tabletmanager/commands_test.go @@ -29,7 +29,6 @@ import ( "vitess.io/vitess/go/json2" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" @@ -44,7 +43,6 @@ var ( // TabletCommands tests the basic tablet commands func TestTabletCommands(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &primaryTabletParams) @@ -185,7 +183,6 @@ func assertExecuteMultiFetch(t *testing.T, qr string) { func TestHook(t *testing.T) { // test a regular program works - defer cluster.PanicHandler(t) runHookAndAssert(t, []string{ "ExecuteHook", primaryTablet.Alias, "test.sh", "--", "--flag1", "--param1=hello"}, 0, false, "") @@ -226,7 +223,6 @@ func runHookAndAssert(t *testing.T, params []string, expectedStatus int64, expec func TestShardReplicationFix(t *testing.T) { // make sure the replica is in the replication graph, 2 nodes: 1 primary, 1 replica - defer cluster.PanicHandler(t) result, err := clusterInstance.VtctldClientProcess.GetShardReplication(keyspaceName, shardName, cell) require.Nil(t, err, "error should be Nil") require.NotNil(t, result[cell], "result should not be Nil") @@ -250,7 +246,6 @@ func TestShardReplicationFix(t *testing.T) { } func TestGetSchema(t *testing.T) { - defer cluster.PanicHandler(t) res, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("GetSchema", "--include-views", "--tables", "t1,v1", diff --git a/go/test/endtoend/tabletmanager/custom_rule_topo_test.go b/go/test/endtoend/tabletmanager/custom_rule_topo_test.go index 0c6e056af36..c393e7c4646 100644 --- a/go/test/endtoend/tabletmanager/custom_rule_topo_test.go +++ b/go/test/endtoend/tabletmanager/custom_rule_topo_test.go @@ -33,7 +33,6 @@ import ( func TestTopoCustomRule(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &primaryTabletParams) require.NoError(t, err) @@ -55,7 +54,7 @@ func TestTopoCustomRule(t *testing.T) { require.NoError(t, err) // Copy config file into topo. - err = clusterInstance.VtctlclientProcess.ExecuteCommand("TopoCp", "--", "--to_topo", topoCustomRuleFile, topoCustomRulePath) + err = clusterInstance.VtctldClientProcess.ExecuteCommand("--server", "internal", "WriteTopologyPath", topoCustomRuleFile, topoCustomRulePath) require.Nil(t, err, "error should be Nil") // Set extra tablet args for topo custom rule @@ -101,7 +100,7 @@ func TestTopoCustomRule(t *testing.T) { err = os.WriteFile(topoCustomRuleFile, data, 0777) require.NoError(t, err) - err = clusterInstance.VtctlclientProcess.ExecuteCommand("TopoCp", "--", "--to_topo", topoCustomRuleFile, topoCustomRulePath) + err = clusterInstance.VtctldClientProcess.ExecuteCommand("--server", "internal", "WriteTopologyPath", topoCustomRuleFile, topoCustomRulePath) require.Nil(t, err, "error should be Nil") // And wait until the query fails with the right error. diff --git a/go/test/endtoend/tabletmanager/lock_unlock_test.go b/go/test/endtoend/tabletmanager/lock_unlock_test.go index 79286438698..f636f52c353 100644 --- a/go/test/endtoend/tabletmanager/lock_unlock_test.go +++ b/go/test/endtoend/tabletmanager/lock_unlock_test.go @@ -30,12 +30,10 @@ import ( "github.com/stretchr/testify/assert" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" ) // TestLockAndUnlock tests the lock ability by locking a replica and asserting it does not see changes func TestLockAndUnlock(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &primaryTabletParams) @@ -76,7 +74,6 @@ func TestLockAndUnlock(t *testing.T) { // TestStartReplicationUntilAfter tests by writing three rows, noting the gtid after each, and then replaying them one by one func TestStartReplicationUntilAfter(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &primaryTabletParams) @@ -130,7 +127,6 @@ func TestStartReplicationUntilAfter(t *testing.T) { // TestLockAndTimeout tests that the lock times out and updates can be seen after timeout func TestLockAndTimeout(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() primaryConn, err := mysql.Connect(ctx, &primaryTabletParams) diff --git a/go/test/endtoend/tabletmanager/main_test.go b/go/test/endtoend/tabletmanager/main_test.go index 3c2eb68df5e..b613f061522 100644 --- a/go/test/endtoend/tabletmanager/main_test.go +++ b/go/test/endtoend/tabletmanager/main_test.go @@ -79,7 +79,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -105,7 +104,6 @@ func TestMain(m *testing.M) { "--heartbeat_enable", "--health_check_interval", tabletHealthcheckRefreshInterval.String(), "--unhealthy_threshold", tabletUnhealthyThreshold.String(), - "--twopc_enable", "--twopc_abandon_age", "200", } diff --git a/go/test/endtoend/tabletmanager/primary/tablet_test.go b/go/test/endtoend/tabletmanager/primary/tablet_test.go index 297e5540fac..aaff0ff00a0 100644 --- a/go/test/endtoend/tabletmanager/primary/tablet_test.go +++ b/go/test/endtoend/tabletmanager/primary/tablet_test.go @@ -69,7 +69,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -116,7 +115,6 @@ func TestMain(m *testing.M) { } func TestRepeatedInitShardPrimary(t *testing.T) { - defer cluster.PanicHandler(t) // Test that using InitShardPrimary can go back and forth between 2 hosts. // Make replica tablet as primary @@ -155,7 +153,6 @@ func TestRepeatedInitShardPrimary(t *testing.T) { } func TestPrimaryRestartSetsPTSTimestamp(t *testing.T) { - defer cluster.PanicHandler(t) // Test that PTS timestamp is set when we restart the PRIMARY vttablet. // PTS = PrimaryTermStart. // See StreamHealthResponse.primary_term_start_timestamp for details. diff --git a/go/test/endtoend/tabletmanager/qps_test.go b/go/test/endtoend/tabletmanager/qps_test.go index 0611feada12..0ce41f04a63 100644 --- a/go/test/endtoend/tabletmanager/qps_test.go +++ b/go/test/endtoend/tabletmanager/qps_test.go @@ -24,12 +24,10 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) func TestQPS(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ diff --git a/go/test/endtoend/tabletmanager/replication_manager/tablet_test.go b/go/test/endtoend/tabletmanager/replication_manager/tablet_test.go index df8c1f26c4e..75c6e8d4cc8 100644 --- a/go/test/endtoend/tabletmanager/replication_manager/tablet_test.go +++ b/go/test/endtoend/tabletmanager/replication_manager/tablet_test.go @@ -73,7 +73,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go b/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go index 685c361cef7..b1abec3a6b7 100644 --- a/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go +++ b/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go @@ -83,7 +83,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/tabletmanager/tablet_health_test.go b/go/test/endtoend/tabletmanager/tablet_health_test.go index bf3747fde29..061528682d2 100644 --- a/go/test/endtoend/tabletmanager/tablet_health_test.go +++ b/go/test/endtoend/tabletmanager/tablet_health_test.go @@ -39,7 +39,6 @@ import ( // TabletReshuffle test if a vttablet can be pointed at an existing mysql func TestTabletReshuffle(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &primaryTabletParams) @@ -92,7 +91,6 @@ func TestTabletReshuffle(t *testing.T) { func TestHealthCheck(t *testing.T) { // Add one replica that starts not initialized - defer cluster.PanicHandler(t) ctx := context.Background() clusterInstance.DisableVTOrcRecoveries(t) defer clusterInstance.EnableVTOrcRecoveries(t) @@ -200,7 +198,6 @@ func TestHealthCheck(t *testing.T) { // TestHealthCheckSchemaChangeSignal tests the tables and views, which report their schemas have changed in the output of a StreamHealth. func TestHealthCheckSchemaChangeSignal(t *testing.T) { // Add one replica that starts not initialized - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := clusterInstance.GetVTParams(keyspaceName) @@ -381,7 +378,6 @@ func TestHealthCheckDrainedStateDoesNotShutdownQueryService(t *testing.T) { // - the query service won't be shutdown // Wait if tablet is not in service state - defer cluster.PanicHandler(t) clusterInstance.DisableVTOrcRecoveries(t) defer clusterInstance.EnableVTOrcRecoveries(t) err := rdonlyTablet.VttabletProcess.WaitForTabletStatus("SERVING") diff --git a/go/test/endtoend/tabletmanager/tablet_security_policy_test.go b/go/test/endtoend/tabletmanager/tablet_security_policy_test.go index b3b11405abb..90397a737ef 100644 --- a/go/test/endtoend/tabletmanager/tablet_security_policy_test.go +++ b/go/test/endtoend/tabletmanager/tablet_security_policy_test.go @@ -29,7 +29,6 @@ import ( ) func TestFallbackSecurityPolicy(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() mTablet := clusterInstance.NewVttabletInstance("replica", 0, "") @@ -84,7 +83,6 @@ func assertAllowedURLTest(t *testing.T, url string) { } func TestDenyAllSecurityPolicy(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() mTablet := clusterInstance.NewVttabletInstance("replica", 0, "") @@ -116,7 +114,6 @@ func TestDenyAllSecurityPolicy(t *testing.T) { } func TestReadOnlySecurityPolicy(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() mTablet := clusterInstance.NewVttabletInstance("replica", 0, "") diff --git a/go/test/endtoend/tabletmanager/tablet_test.go b/go/test/endtoend/tabletmanager/tablet_test.go index 1d8e897a4d2..2ded055230f 100644 --- a/go/test/endtoend/tabletmanager/tablet_test.go +++ b/go/test/endtoend/tabletmanager/tablet_test.go @@ -31,7 +31,6 @@ import ( // TestEnsureDB tests that vttablet creates the db as needed func TestEnsureDB(t *testing.T) { - defer cluster.PanicHandler(t) // Create new tablet tablet := clusterInstance.NewVttabletInstance("replica", 0, "") @@ -67,7 +66,6 @@ func TestEnsureDB(t *testing.T) { // TestResetReplicationParameters tests that the RPC ResetReplicationParameters works as intended. func TestResetReplicationParameters(t *testing.T) { - defer cluster.PanicHandler(t) // Create new tablet tablet := clusterInstance.NewVttabletInstance("replica", 0, "") diff --git a/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go b/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go index 831348cfcde..3b8111121fe 100644 --- a/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go +++ b/go/test/endtoend/tabletmanager/throttler_topo/throttler_test.go @@ -100,7 +100,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -155,7 +154,7 @@ func TestMain(m *testing.M) { Host: clusterInstance.Hostname, Port: clusterInstance.VtgateMySQLPort, } - clusterInstance.VtctldClientProcess = *cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) + clusterInstance.VtctldClientProcess = *cluster.VtctldClientProcessInstance(clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TopoPort, "localhost", clusterInstance.TmpDirectory) return m.Run() }() @@ -265,7 +264,6 @@ func vtgateExec(t *testing.T, query string, expectError string) *sqltypes.Result } func TestInitialThrottler(t *testing.T) { - defer cluster.PanicHandler(t) t.Run("validating OK response from disabled throttler", func(t *testing.T) { waitForThrottleCheckStatus(t, primaryTablet, tabletmanagerdatapb.CheckThrottlerResponseCode_OK) @@ -408,7 +406,6 @@ func TestInitialThrottler(t *testing.T) { } func TestThrottleViaApplySchema(t *testing.T) { - defer cluster.PanicHandler(t) t.Run("throttling via ApplySchema", func(t *testing.T) { vtctlParams := &cluster.ApplySchemaParams{DDLStrategy: "online"} _, err := clusterInstance.VtctldClientProcess.ApplySchemaWithOutput( @@ -451,7 +448,6 @@ func TestThrottleViaApplySchema(t *testing.T) { } func TestThrottlerAfterMetricsCollected(t *testing.T) { - defer cluster.PanicHandler(t) // By this time metrics will have been collected. We expect no lag, and something like: // {"StatusCode":200,"Value":0.282278,"Threshold":1,"Message":""} @@ -478,7 +474,6 @@ func TestThrottlerAfterMetricsCollected(t *testing.T) { } func TestLag(t *testing.T) { - defer cluster.PanicHandler(t) // Temporarily disable VTOrc recoveries because we want to // STOP replication specifically in order to increase the // lag and we DO NOT want VTOrc to try and fix this. @@ -609,7 +604,6 @@ func TestLag(t *testing.T) { } func TestNoReplicas(t *testing.T) { - defer cluster.PanicHandler(t) t.Run("changing replica to RDONLY", func(t *testing.T) { err := clusterInstance.VtctldClientProcess.ExecuteCommand("ChangeTabletType", replicaTablet.Alias, "RDONLY") assert.NoError(t, err) @@ -627,7 +621,6 @@ func TestNoReplicas(t *testing.T) { } func TestCustomQuery(t *testing.T) { - defer cluster.PanicHandler(t) t.Run("enabling throttler with custom query and threshold", func(t *testing.T) { req := &vtctldatapb.UpdateThrottlerConfigRequest{Enable: true, Threshold: customThreshold, CustomQuery: customQuery} @@ -692,7 +685,6 @@ func TestCustomQuery(t *testing.T) { } func TestRestoreDefaultQuery(t *testing.T) { - defer cluster.PanicHandler(t) // Validate going back from custom-query to default-query (replication lag) still works. t.Run("enabling throttler with default query and threshold", func(t *testing.T) { diff --git a/go/test/endtoend/throttler/util.go b/go/test/endtoend/throttler/util.go index 44998fc8125..588efb090cc 100644 --- a/go/test/endtoend/throttler/util.go +++ b/go/test/endtoend/throttler/util.go @@ -97,7 +97,7 @@ func GetThrottlerStatusRaw(vtctldProcess *cluster.VtctldClientProcess, tablet *c return result, err } -// UpdateThrottlerTopoConfig runs vtctlclient UpdateThrottlerConfig. +// UpdateThrottlerTopoConfig runs vtctldclient UpdateThrottlerConfig. // This retries the command until it succeeds or times out as the // SrvKeyspace record may not yet exist for a newly created // Keyspace that is still initializing before it becomes serving. @@ -212,7 +212,7 @@ func GetThrottlerStatus(vtctldProcess *cluster.VtctldClientProcess, tablet *clus return resp.Status, err } -// UpdateThrottlerTopoConfig runs vtctlclient UpdateThrottlerConfig. +// UpdateThrottlerTopoConfig runs vtctldclient UpdateThrottlerConfig. // This retries the command until it succeeds or times out as the // SrvKeyspace record may not yet exist for a newly created // Keyspace that is still initializing before it becomes serving. @@ -266,7 +266,7 @@ func WaitForSrvKeyspace(clusterInstance *cluster.LocalProcessCluster, cell, keys } } -// throttleAppRaw runs vtctlclient UpdateThrottlerConfig with --throttle-app flags +// throttleAppRaw runs vtctldclient UpdateThrottlerConfig with --throttle-app flags // This retries the command until it succeeds or times out as the // SrvKeyspace record may not yet exist for a newly created // Keyspace that is still initializing before it becomes serving. diff --git a/go/test/endtoend/topoconncache/main_test.go b/go/test/endtoend/topoconncache/main_test.go index 26eb3918a0b..512998a3769 100644 --- a/go/test/endtoend/topoconncache/main_test.go +++ b/go/test/endtoend/topoconncache/main_test.go @@ -97,7 +97,6 @@ Topology: We create a keyspace with two shards , having 3 tablets each. Primarie to 'zone1' and replicas/rdonly belongs to cell2. */ func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -117,12 +116,12 @@ func TestMain(m *testing.M) { if err != nil { return 1, err } - err = clusterInstance.VtctlProcess.AddCellInfo(cell2) + err = clusterInstance.VtctldClientProcess.AddCellInfo(cell2) if err != nil { return 1, err } - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TopoPort, "localhost", clusterInstance.TmpDirectory) _, err = vtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", keyspaceName, "--durability-policy=semi_sync") if err != nil { return 1, err diff --git a/go/test/endtoend/topoconncache/topo_conn_cache_test.go b/go/test/endtoend/topoconncache/topo_conn_cache_test.go index 082ecc5717f..edd40226ed8 100644 --- a/go/test/endtoend/topoconncache/topo_conn_cache_test.go +++ b/go/test/endtoend/topoconncache/topo_conn_cache_test.go @@ -37,7 +37,6 @@ import ( 4. 'ListAllTablets' should return all the new tablets. */ func TestVtctldListAllTablets(t *testing.T) { - defer cluster.PanicHandler(t) url := fmt.Sprintf("http://%s:%d/api/keyspaces/", clusterInstance.Hostname, clusterInstance.VtctldHTTPPort) testURL(t, url, "keyspace url") @@ -117,9 +116,9 @@ func deleteTablet(t *testing.T, tablet *cluster.Vttablet) { func addCellback(t *testing.T) { // creating new cell , with same name as previously deleted one but at a different root path. - clusterInstance.VtctlProcess.TopoRootPath = "/org1/obj1/" + clusterInstance.VtctldClientProcess.TopoRootPath = "/org1/obj1/" - err := clusterInstance.VtctlProcess.AddCellInfo(cell2) + err := clusterInstance.VtctldClientProcess.AddCellInfo(cell2) require.NoError(t, err) // create new vttablets diff --git a/go/test/endtoend/topotest/consul/main_test.go b/go/test/endtoend/topotest/consul/main_test.go index 0f6fa6ce554..b71551dc6b7 100644 --- a/go/test/endtoend/topotest/consul/main_test.go +++ b/go/test/endtoend/topotest/consul/main_test.go @@ -63,7 +63,6 @@ CREATE TABLE t1 ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -99,7 +98,6 @@ func TestMain(m *testing.M) { } func TestTopoRestart(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -145,7 +143,7 @@ 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) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) // Acquire a shard lock. @@ -187,7 +185,7 @@ func TestShardLocking(t *testing.T) { // 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) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) // Acquire a keyspace lock. diff --git a/go/test/endtoend/topotest/etcd2/main_test.go b/go/test/endtoend/topotest/etcd2/main_test.go index 67b0dbbc8f7..b274219b41a 100644 --- a/go/test/endtoend/topotest/etcd2/main_test.go +++ b/go/test/endtoend/topotest/etcd2/main_test.go @@ -64,7 +64,6 @@ CREATE TABLE t1 ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -99,7 +98,6 @@ func TestMain(m *testing.M) { } func TestTopoDownServingQuery(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -124,7 +122,7 @@ func TestTopoDownServingQuery(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) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) // Acquire a shard lock. @@ -166,7 +164,7 @@ func TestShardLocking(t *testing.T) { // 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) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) // Acquire a keyspace lock. @@ -205,7 +203,7 @@ func TestKeyspaceLocking(t *testing.T) { // TestLockingWithTTL tests that locking with the TTL override works as intended. func TestLockingWithTTL(t *testing.T) { // Create the topo server connection. - ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) ctx := context.Background() @@ -226,7 +224,7 @@ func TestLockingWithTTL(t *testing.T) { // TestNamedLocking tests that named locking works as intended. func TestNamedLocking(t *testing.T) { // Create topo server connection. - ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) ctx := context.Background() diff --git a/go/test/endtoend/topotest/zk2/main_test.go b/go/test/endtoend/topotest/zk2/main_test.go index 48636331747..95a2fc13894 100644 --- a/go/test/endtoend/topotest/zk2/main_test.go +++ b/go/test/endtoend/topotest/zk2/main_test.go @@ -63,7 +63,6 @@ CREATE TABLE t1 ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -99,7 +98,6 @@ func TestMain(m *testing.M) { } func TestTopoDownServingQuery(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -121,7 +119,7 @@ func TestTopoDownServingQuery(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) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) // Acquire a shard lock. @@ -163,7 +161,7 @@ func TestShardLocking(t *testing.T) { // 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) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) // Acquire a keyspace lock. diff --git a/go/test/endtoend/transaction/benchmark/bench_test.go b/go/test/endtoend/transaction/benchmark/bench_test.go new file mode 100644 index 00000000000..553919f893e --- /dev/null +++ b/go/test/endtoend/transaction/benchmark/bench_test.go @@ -0,0 +1,178 @@ +/* +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 benchmark + +import ( + "context" + _ "embed" + "flag" + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/exp/rand" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/test/endtoend/cluster" + twopcutil "vitess.io/vitess/go/test/endtoend/transaction/twopc/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" +) + +var ( + clusterInstance *cluster.LocalProcessCluster + vtParams mysql.ConnParams + 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) { + flag.Parse() + + exitcode := func() int { + clusterInstance = cluster.NewCluster(cell, hostname) + defer clusterInstance.Teardown() + + // Start topo server + if err := clusterInstance.StartTopo(); err != nil { + return 1 + } + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + SchemaSQL: SchemaSQL, + VSchema: VSchema, + SidecarDBName: sidecarDBName, + DurabilityPolicy: policy.DurabilitySemiSync, + } + if err := clusterInstance.StartKeyspace(*keyspace, []string{"-40", "40-80", "80-c0", "c0-"}, 1, false); err != nil { + return 1 + } + + // Start Vtgate + if err := clusterInstance.StartVtgate(); err != nil { + return 1 + } + vtParams = clusterInstance.GetVTParams(keyspaceName) + + return m.Run() + }() + os.Exit(exitcode) +} + +func start(b *testing.B) (*mysql.Conn, func()) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(b, err) + cleanup(b) + + return conn, func() { + conn.Close() + cleanup(b) + } +} + +func cleanup(b *testing.B) { + twopcutil.ClearOutTable(b, vtParams, "test") +} + +// BenchmarkTwoPCCommit benchmarks the performance of a two-phase commit transaction +// with varying numbers of inserts. +// Recommended run options: +/* +export ver=v1 p=~/path && go test \ +-run '^$' -bench '^BenchmarkTwoPCCommit' \ +-benchtime 3s -count 6 -cpu 8 +| tee $p/${ver}.txt +*/ +func BenchmarkTwoPCCommit(b *testing.B) { + // Pre-generate 100 random strings + const sampleSize = 100 + randomStrings := generateRandomStrings(sampleSize, 25) + + // Define table-driven test cases + testCases := []struct { + name string + shardStart []int // Number of different shard involved per transaction + }{ + {name: "SingleShard", shardStart: []int{1}}, + {name: "TwoShards", shardStart: []int{3, 4}}, + {name: "ThreeShards", shardStart: []int{2, 3, 4}}, + {name: "FourShards", shardStart: []int{4, 3, 2, 1}}, + } + + // Incremental id for inserts + id := 1 + + for _, tc := range testCases { + for _, commitMode := range []string{"twopc", "multi"} { + conn, _ := start(b) + _, err := conn.ExecuteFetch(fmt.Sprintf("set transaction_mode = %s", commitMode), 0, false) + if err != nil { + b.Fatal(err) + } + b.Run(commitMode+tc.name, func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err = conn.ExecuteFetch("begin", 0, false) + if err != nil { + b.Fatal(err) + } + + randomMsg := randomStrings[id%sampleSize] + // Perform the specified number of inserts to specific shards + for _, val := range tc.shardStart { + _, err = conn.ExecuteFetch(fmt.Sprintf("insert into test(id, msg) values(%d, '%s')", val+(4*id), randomMsg), 0, false) + if err != nil { + b.Fatal(err) + } + } + id++ + + _, err = conn.ExecuteFetch("commit", 0, false) + if err != nil { + b.Fatal(err) + } + } + }) + conn.Close() + } + } +} + +// generateRandomStrings generates 'n' random strings, each of length 'length'. +func generateRandomStrings(n, length int) []string { + const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + result := make([]string, n) + for i := range result { + b := make([]byte, length) + for j := range b { + b[j] = charset[rand.Intn(len(charset))] + } + result[i] = string(b) + } + return result +} diff --git a/go/test/endtoend/transaction/benchmark/schema.sql b/go/test/endtoend/transaction/benchmark/schema.sql new file mode 100644 index 00000000000..44e92ed483f --- /dev/null +++ b/go/test/endtoend/transaction/benchmark/schema.sql @@ -0,0 +1,5 @@ +create table test ( + id bigint, + msg varchar(25), + primary key (id) +) Engine=InnoDB; \ No newline at end of file diff --git a/go/test/endtoend/transaction/benchmark/vschema.json b/go/test/endtoend/transaction/benchmark/vschema.json new file mode 100644 index 00000000000..2c66d6c65fe --- /dev/null +++ b/go/test/endtoend/transaction/benchmark/vschema.json @@ -0,0 +1,18 @@ +{ + "sharded":true, + "vindexes": { + "hash_index": { + "type": "reverse_bits" + } + }, + "tables": { + "test": { + "column_vindexes": [ + { + "column": "id", + "name": "hash_index" + } + ] + } + } +} \ No newline at end of file diff --git a/go/test/endtoend/transaction/restart/main_test.go b/go/test/endtoend/transaction/restart/main_test.go index 01185b5fa59..caa3111ad49 100644 --- a/go/test/endtoend/transaction/restart/main_test.go +++ b/go/test/endtoend/transaction/restart/main_test.go @@ -41,7 +41,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/transaction/rollback/txn_rollback_shutdown_test.go b/go/test/endtoend/transaction/rollback/txn_rollback_shutdown_test.go index 2dff9f7b95f..c7bef098c05 100644 --- a/go/test/endtoend/transaction/rollback/txn_rollback_shutdown_test.go +++ b/go/test/endtoend/transaction/rollback/txn_rollback_shutdown_test.go @@ -48,7 +48,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -87,7 +86,6 @@ func TestMain(m *testing.M) { } func TestTransactionRollBackWhenShutDown(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -122,7 +120,6 @@ func TestTransactionRollBackWhenShutDown(t *testing.T) { } func TestErrorInAutocommitSession(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) diff --git a/go/test/endtoend/transaction/single/main_test.go b/go/test/endtoend/transaction/single/main_test.go index ec2dbd6378a..1eab3cea276 100644 --- a/go/test/endtoend/transaction/single/main_test.go +++ b/go/test/endtoend/transaction/single/main_test.go @@ -46,7 +46,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/transaction/twopc/fuzz/main_test.go b/go/test/endtoend/transaction/twopc/fuzz/main_test.go index 15574c8d072..3516bdefe05 100644 --- a/go/test/endtoend/transaction/twopc/fuzz/main_test.go +++ b/go/test/endtoend/transaction/twopc/fuzz/main_test.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/transaction/twopc/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) var ( @@ -48,7 +49,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode := func() int { @@ -70,7 +70,6 @@ func TestMain(m *testing.M) { "--tablet_refresh_interval", "2s", ) clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, - "--twopc_enable", "--twopc_abandon_age", "1", "--migration_check_interval", "2s", ) @@ -80,7 +79,7 @@ func TestMain(m *testing.M) { Name: keyspaceName, SchemaSQL: SchemaSQL, VSchema: VSchema, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } if err := clusterInstance.StartKeyspace(*keyspace, []string{"-40", "40-80", "80-"}, 2, false); err != nil { return 1 @@ -91,7 +90,7 @@ func TestMain(m *testing.M) { Name: unshardedKeyspaceName, SchemaSQL: "", VSchema: "{}", - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } if err := clusterInstance.StartUnshardedKeyspace(*unshardedKeyspace, 2, false); err != nil { return 1 @@ -122,7 +121,6 @@ func start(t *testing.T) (*mysql.Conn, func()) { } func cleanup(t *testing.T) { - cluster.PanicHandler(t) utils.ClearOutTable(t, vtParams, "twopc_fuzzer_insert") utils.ClearOutTable(t, vtParams, "twopc_fuzzer_update") diff --git a/go/test/endtoend/transaction/twopc/main_test.go b/go/test/endtoend/transaction/twopc/main_test.go index 631b29647c9..7a2f7e8676e 100644 --- a/go/test/endtoend/transaction/twopc/main_test.go +++ b/go/test/endtoend/transaction/twopc/main_test.go @@ -32,6 +32,7 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" @@ -61,7 +62,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode := func() int { @@ -78,11 +78,9 @@ func TestMain(m *testing.M) { // Set extra args for twopc clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, - "--transaction_mode", "TWOPC", "--grpc_use_effective_callerid", ) clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, - "--twopc_enable", "--twopc_abandon_age", "1", "--queryserver-config-transaction-cap", "3", "--queryserver-config-transaction-timeout", "400s", @@ -95,7 +93,7 @@ func TestMain(m *testing.M) { SchemaSQL: SchemaSQL, VSchema: VSchema, SidecarDBName: sidecarDBName, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } if err := clusterInstance.StartKeyspace(*keyspace, []string{"-40", "40-80", "80-"}, 2, false); err != nil { return 1 @@ -105,6 +103,13 @@ func TestMain(m *testing.M) { if err := clusterInstance.StartVtgate(); err != nil { return 1 } + clusterInstance.VtgateProcess.Config.TransactionMode = "TWOPC" + if err := clusterInstance.VtgateProcess.RewriteConfiguration(); err != nil { + return 1 + } + if err := clusterInstance.VtgateProcess.WaitForConfig(`"transaction_mode":"TWOPC"`); err != nil { + return 1 + } vtParams = clusterInstance.GetVTParams(keyspaceName) vtgateGrpcAddress = fmt.Sprintf("%s:%d", clusterInstance.Hostname, clusterInstance.VtgateGrpcPort) @@ -140,12 +145,14 @@ func start(t *testing.T) (*mysql.Conn, func()) { } func cleanup(t *testing.T) { - cluster.PanicHandler(t) twopcutil.ClearOutTable(t, vtParams, "twopc_user") twopcutil.ClearOutTable(t, vtParams, "twopc_t1") twopcutil.ClearOutTable(t, vtParams, "twopc_lookup") twopcutil.ClearOutTable(t, vtParams, "lookup_unique") twopcutil.ClearOutTable(t, vtParams, "lookup") + twopcutil.ClearOutTable(t, vtParams, "twopc_consistent_lookup") + twopcutil.ClearOutTable(t, vtParams, "consistent_lookup_unique") + twopcutil.ClearOutTable(t, vtParams, "consistent_lookup") sm.reset() } @@ -165,7 +172,6 @@ func startWithMySQL(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/transaction/twopc/metric/main_test.go b/go/test/endtoend/transaction/twopc/metric/main_test.go index 73cc380a900..0018f5d45d8 100644 --- a/go/test/endtoend/transaction/twopc/metric/main_test.go +++ b/go/test/endtoend/transaction/twopc/metric/main_test.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" twopcutil "vitess.io/vitess/go/test/endtoend/transaction/twopc/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) var ( @@ -48,7 +49,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode := func() int { @@ -69,7 +69,6 @@ func TestMain(m *testing.M) { "--grpc_use_effective_callerid", ) clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, - "--twopc_enable", "--twopc_abandon_age", "1", "--queryserver-config-transaction-cap", "100", ) @@ -80,7 +79,7 @@ func TestMain(m *testing.M) { SchemaSQL: SchemaSQL, VSchema: VSchema, SidecarDBName: sidecarDBName, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } if err := clusterInstance.StartKeyspace(*keyspace, []string{"-40", "40-80", "80-"}, 2, false); err != nil { return 1 @@ -111,7 +110,6 @@ func start(t *testing.T) (*mysql.Conn, func()) { } func cleanup(t *testing.T) { - cluster.PanicHandler(t) twopcutil.ClearOutTable(t, vtParams, "twopc_user") twopcutil.ClearOutTable(t, vtParams, "twopc_t1") } diff --git a/go/test/endtoend/transaction/twopc/schema.sql b/go/test/endtoend/transaction/twopc/schema.sql index aff839eabe9..ceff8c16af5 100644 --- a/go/test/endtoend/transaction/twopc/schema.sql +++ b/go/test/endtoend/transaction/twopc/schema.sql @@ -30,15 +30,38 @@ create table twopc_lookup create table lookup ( - col varchar(128), + col bigint, id bigint, keyspace_id varbinary(100), - primary key (id) + primary key (col, id) ) Engine = InnoDB; create table lookup_unique ( - col_unique varchar(128), + col_unique bigint, + keyspace_id varbinary(100), + primary key (col_unique) +) Engine = InnoDB; + +create table twopc_consistent_lookup +( + id bigint, + col bigint, + col_unique bigint, + primary key (id) +) Engine=InnoDB; + +create table consistent_lookup +( + col bigint, + id bigint, + keyspace_id varbinary(100), + primary key (col, id) +) Engine = InnoDB; + +create table consistent_lookup_unique +( + col_unique bigint, keyspace_id varbinary(100), primary key (col_unique) ) Engine = InnoDB; diff --git a/go/test/endtoend/transaction/twopc/stress/main_test.go b/go/test/endtoend/transaction/twopc/stress/main_test.go index 76cd05df50a..977fa3f6fd6 100644 --- a/go/test/endtoend/transaction/twopc/stress/main_test.go +++ b/go/test/endtoend/transaction/twopc/stress/main_test.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/transaction/twopc/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) var ( @@ -48,7 +49,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode := func() int { @@ -70,7 +70,6 @@ func TestMain(m *testing.M) { "--tablet_refresh_interval", "2s", ) clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, - "--twopc_enable", "--twopc_abandon_age", "1", "--migration_check_interval", "2s", "--onterm_timeout", "1s", @@ -82,7 +81,7 @@ func TestMain(m *testing.M) { Name: keyspaceName, SchemaSQL: SchemaSQL, VSchema: VSchema, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } if err := clusterInstance.StartKeyspace(*keyspace, []string{"-40", "40-80", "80-"}, 2, false); err != nil { return 1 @@ -93,7 +92,7 @@ func TestMain(m *testing.M) { Name: unshardedKeyspaceName, SchemaSQL: "", VSchema: "{}", - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } if err := clusterInstance.StartUnshardedKeyspace(*unshardedKeyspace, 2, false); err != nil { return 1 @@ -124,7 +123,6 @@ func start(t *testing.T) (*mysql.Conn, func()) { } func cleanup(t *testing.T) { - cluster.PanicHandler(t) utils.ClearOutTable(t, vtParams, "twopc_t1") utils.ClearOutTable(t, vtParams, "twopc_settings") } diff --git a/go/test/endtoend/transaction/twopc/twopc_test.go b/go/test/endtoend/transaction/twopc/twopc_test.go index 8e249365bda..b7f7c11fba9 100644 --- a/go/test/endtoend/transaction/twopc/twopc_test.go +++ b/go/test/endtoend/transaction/twopc/twopc_test.go @@ -44,6 +44,38 @@ import ( "vitess.io/vitess/go/vt/vttablet/grpctmclient" ) +// TestDynamicConfig tests that transaction mode is dynamically configurable. +func TestDynamicConfig(t *testing.T) { + conn, closer := start(t) + defer closer() + defer conn.Close() + + // Ensure that initially running a distributed transaction is possible. + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "insert into twopc_t1(id, col) values(4, 4)") + utils.Exec(t, conn, "insert into twopc_t1(id, col) values(6, 4)") + utils.Exec(t, conn, "insert into twopc_t1(id, col) values(9, 4)") + utils.Exec(t, conn, "commit") + + clusterInstance.VtgateProcess.Config.TransactionMode = "SINGLE" + defer func() { + clusterInstance.VtgateProcess.Config.TransactionMode = "TWOPC" + err := clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + }() + err := clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + err = clusterInstance.VtgateProcess.WaitForConfig(`"transaction_mode":"SINGLE"`) + require.NoError(t, err) + + // After the config changes verify running a distributed transaction fails. + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "insert into twopc_t1(id, col) values(20, 4)") + _, err = utils.ExecAllowError(t, conn, "insert into twopc_t1(id, col) values(22, 4)") + require.ErrorContains(t, err, "multi-db transaction attempted") + utils.Exec(t, conn, "rollback") +} + // 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) { @@ -563,7 +595,11 @@ func compareMaps(t *testing.T, expected, actual map[string][]string, flexibleExp // TestDTResolveAfterMMCommit tests that transaction is committed on recovery // failure after MM commit. func TestDTResolveAfterMMCommit(t *testing.T) { - defer cleanup(t) + initconn, closer := start(t) + defer closer() + + // Do an insertion into a table that has a consistent lookup vindex. + utils.Exec(t, initconn, "insert into twopc_consistent_lookup(id, col, col_unique) values(4, 4, 6)") vtgateConn, err := cluster.DialVTGate(context.Background(), t.Name(), vtgateGrpcAddress, "dt_user", "") require.NoError(t, err) @@ -589,6 +625,10 @@ func TestDTResolveAfterMMCommit(t *testing.T) { require.NoError(t, err) _, err = conn.Execute(qCtx, "insert into twopc_user(id, name) values(10,'apa')", nil) require.NoError(t, err) + // Also do an update to a table that has a consistent lookup vindex. + // We expect to see only the pre-session changes in the logs. + _, err = conn.Execute(qCtx, "update twopc_consistent_lookup set col = 22 where id = 4", nil) + require.NoError(t, err) // The caller ID is used to simulate the failure at the desired point. newCtx := callerid.NewContext(qCtx, callerid.NewEffectiveCallerID("MMCommitted_FailNow", "", ""), nil) @@ -625,7 +665,9 @@ func TestDTResolveAfterMMCommit(t *testing.T) { }, "ks.redo_statement:-40": { "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (10, 'apa')\")]", + "insert:[VARCHAR(\"dtid-1\") INT64(2) BLOB(\"update twopc_consistent_lookup set col = 22 where id = 4 limit 10001 /* INT64 */\")]", "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (10, 'apa')\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(2) BLOB(\"update twopc_consistent_lookup set col = 22 where id = 4 limit 10001 /* INT64 */\")]", }, "ks.redo_statement:40-80": { "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (8, 'bar')\")]", @@ -641,6 +683,12 @@ func TestDTResolveAfterMMCommit(t *testing.T) { `insert:[INT64(7) VARCHAR("foo")]`, `insert:[INT64(9) VARCHAR("baz")]`, }, + "ks.consistent_lookup:-40": { + "insert:[INT64(22) INT64(4) VARBINARY(\" \\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + "ks.twopc_consistent_lookup:-40": { + "update:[INT64(4) INT64(22) INT64(6)]", + }, } assert.Equal(t, expectations, logTable, "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) @@ -649,7 +697,11 @@ func TestDTResolveAfterMMCommit(t *testing.T) { // TestDTResolveAfterRMPrepare tests that transaction is rolled back on recovery // failure after RM prepare and before MM commit. func TestDTResolveAfterRMPrepare(t *testing.T) { - defer cleanup(t) + initconn, closer := start(t) + defer closer() + + // Do an insertion into a table that has a consistent lookup vindex. + utils.Exec(t, initconn, "insert into twopc_consistent_lookup(id, col, col_unique) values(4, 4, 6)") vtgateConn, err := cluster.DialVTGate(context.Background(), t.Name(), vtgateGrpcAddress, "dt_user", "") require.NoError(t, err) @@ -671,6 +723,10 @@ func TestDTResolveAfterRMPrepare(t *testing.T) { require.NoError(t, err) _, err = conn.Execute(qCtx, "insert into twopc_user(id, name) values(8,'bar')", nil) require.NoError(t, err) + // Also do an update to a table that has a consistent lookup vindex. + // We expect to see only the pre-session changes in the logs. + _, err = conn.Execute(qCtx, "update twopc_consistent_lookup set col = 22 where id = 4", nil) + require.NoError(t, err) // The caller ID is used to simulate the failure at the desired point. newCtx := callerid.NewContext(qCtx, callerid.NewEffectiveCallerID("RMPrepared_FailNow", "", ""), nil) @@ -693,16 +749,29 @@ func TestDTResolveAfterRMPrepare(t *testing.T) { }, "ks.dt_participant:80-": { "insert:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"40-80\")]", + "insert:[VARCHAR(\"dtid-1\") INT64(2) VARCHAR(\"ks\") VARCHAR(\"-40\")]", "delete:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"40-80\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(2) VARCHAR(\"ks\") VARCHAR(\"-40\")]", }, "ks.redo_state:40-80": { "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", }, + "ks.redo_state:-40": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + }, "ks.redo_statement:40-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')\")]", }, + "ks.redo_statement:-40": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"update twopc_consistent_lookup set col = 22 where id = 4 limit 10001 /* INT64 */\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"update twopc_consistent_lookup set col = 22 where id = 4 limit 10001 /* INT64 */\")]", + }, + "ks.consistent_lookup:-40": { + "insert:[INT64(22) INT64(4) VARBINARY(\" \\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, } assert.Equal(t, expectations, logTable, "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) @@ -1349,23 +1418,15 @@ func TestSemiSyncRequiredWithTwoPC(t *testing.T) { // cleanup all the old data. conn, closer := start(t) defer closer() - - out, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=none") - require.NoError(t, err, out) defer func() { - for _, shard := range clusterInstance.Keyspaces[0].Shards { - clusterInstance.VtctldClientProcess.PlannedReparentShard(keyspaceName, shard.Name, shard.Vttablets[0].Alias) - } + reparentAllShards(t, clusterInstance, 0) }() - // After changing the durability policy for the given keyspace to none, we run PRS. - shard := clusterInstance.Keyspaces[0].Shards[2] - newPrimary := shard.Vttablets[1] - _, err = clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput( - "PlannedReparentShard", - fmt.Sprintf("%s/%s", keyspaceName, shard.Name), - "--new-primary", newPrimary.Alias) - require.NoError(t, err) + reparentAllShards(t, clusterInstance, 0) + out, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=none") + require.NoError(t, err, out) + // After changing the durability policy for the given keyspace to none, we run PRS to ensure the changes have taken effect. + reparentAllShards(t, clusterInstance, 1) // A new distributed transaction should fail. utils.Exec(t, conn, "begin") @@ -1378,10 +1439,7 @@ func TestSemiSyncRequiredWithTwoPC(t *testing.T) { _, err = clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync") require.NoError(t, err) - for _, shard := range clusterInstance.Keyspaces[0].Shards { - err = clusterInstance.VtctldClientProcess.PlannedReparentShard(keyspaceName, shard.Name, shard.Vttablets[1].Alias) - require.NoError(t, err) - } + reparentAllShards(t, clusterInstance, 0) // Transaction should now succeed. utils.Exec(t, conn, "begin") @@ -1392,6 +1450,14 @@ func TestSemiSyncRequiredWithTwoPC(t *testing.T) { require.NoError(t, err) } +// reparentAllShards reparents all the shards to the given tablet index for that shard. +func reparentAllShards(t *testing.T, clusterInstance *cluster.LocalProcessCluster, idx int) { + for _, shard := range clusterInstance.Keyspaces[0].Shards { + err := clusterInstance.VtctldClientProcess.PlannedReparentShard(keyspaceName, shard.Name, shard.Vttablets[idx].Alias) + require.NoError(t, err) + } +} + // TestReadTransactionStatus tests that read transaction state rpc works as expected. func TestReadTransactionStatus(t *testing.T) { conn, closer := start(t) @@ -1494,8 +1560,8 @@ func TestVindexes(t *testing.T) { "update:[INT64(6) INT64(9) INT64(9)]", }, "ks.lookup:80-": { - "delete:[VARCHAR(\"4\") INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", - "insert:[VARCHAR(\"9\") INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(9) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, }, }, @@ -1522,8 +1588,8 @@ func TestVindexes(t *testing.T) { "update:[INT64(6) INT64(4) INT64(20)]", }, "ks.lookup_unique:80-": { - "delete:[VARCHAR(\"9\") VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", - "insert:[VARCHAR(\"20\") VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(9) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(20) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, }, }, @@ -1550,10 +1616,10 @@ func TestVindexes(t *testing.T) { "delete:[INT64(6) INT64(4) INT64(9)]", }, "ks.lookup_unique:80-": { - "delete:[VARCHAR(\"9\") VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(9) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, "ks.lookup:80-": { - "delete:[VARCHAR(\"4\") INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, }, }, @@ -1575,10 +1641,10 @@ func TestVindexes(t *testing.T) { "delete:[VARCHAR(\"dtid-3\") INT64(1) BLOB(\"insert into lookup(col, id, keyspace_id) values (4, 20, _binary'(\\\\0\\\\0\\\\0\\\\0\\\\0\\\\0\\\\0')\")]", }, "ks.lookup:80-": { - "insert:[VARCHAR(\"4\") INT64(20) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(4) INT64(20) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, "ks.lookup_unique:-40": { - "insert:[VARCHAR(\"22\") VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(22) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, "ks.twopc_lookup:-40": { "insert:[INT64(20) INT64(4) INT64(22)]", @@ -1628,16 +1694,130 @@ func TestVindexes(t *testing.T) { "delete:[INT64(9) INT64(4) INT64(4)]", }, "ks.lookup_unique:-40": { - "insert:[VARCHAR(\"22\") VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(22) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, "ks.lookup_unique:80-": { - "delete:[VARCHAR(\"4\") VARBINARY(\"\\x90\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) VARBINARY(\"\\x90\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, "ks.lookup:80-": { - "insert:[VARCHAR(\"4\") INT64(20) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", - "delete:[VARCHAR(\"4\") INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", - "insert:[VARCHAR(\"9\") INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", - "delete:[VARCHAR(\"4\") INT64(9) VARBINARY(\"\\x90\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(4) INT64(20) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(9) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) INT64(9) VARBINARY(\"\\x90\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + }, + }, + { + name: "Consistent Lookup Single Update", + initQueries: []string{ + "insert into twopc_consistent_lookup(id, col, col_unique) values(4, 4, 6)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(6, 4, 9)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(9, 4, 4)", + }, + testQueries: []string{ + "begin", + "update twopc_consistent_lookup set col = 9 where col_unique = 9", + "commit", + }, + logExpected: map[string][]string{ + "ks.twopc_consistent_lookup:40-80": { + "update:[INT64(6) INT64(9) INT64(9)]", + }, + "ks.consistent_lookup:80-": { + "insert:[INT64(9) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + }, + }, + { + name: "Consistent Lookup-Unique Single Update", + initQueries: []string{ + "insert into twopc_consistent_lookup(id, col, col_unique) values(4, 4, 6)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(6, 4, 9)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(9, 4, 4)", + }, + testQueries: []string{ + "begin", + "update twopc_consistent_lookup set col_unique = 20 where col_unique = 9", + "commit", + }, + logExpected: map[string][]string{ + "ks.twopc_consistent_lookup:40-80": { + "update:[INT64(6) INT64(4) INT64(20)]", + }, + "ks.consistent_lookup_unique:80-": { + "insert:[INT64(20) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(9) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + }, + }, + { + name: "Consistent Lookup And Consistent Lookup-Unique Single Delete", + initQueries: []string{ + "insert into twopc_consistent_lookup(id, col, col_unique) values(4, 4, 6)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(6, 4, 9)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(9, 4, 4)", + }, + testQueries: []string{ + "begin", + "delete from twopc_consistent_lookup where col_unique = 9", + "commit", + }, + logExpected: map[string][]string{ + "ks.twopc_consistent_lookup:40-80": { + "delete:[INT64(6) INT64(4) INT64(9)]", + }, + "ks.consistent_lookup_unique:80-": { + "delete:[INT64(9) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + "ks.consistent_lookup:80-": { + "delete:[INT64(4) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + }, + }, + { + name: "Consistent Lookup And Consistent Lookup-Unique Mix", + initQueries: []string{ + "insert into twopc_consistent_lookup(id, col, col_unique) values(4, 4, 6)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(6, 4, 9)", + "insert into twopc_consistent_lookup(id, col, col_unique) values(9, 4, 4)", + }, + testQueries: []string{ + "begin", + "insert into twopc_consistent_lookup(id, col, col_unique) values(20, 4, 22)", + "update twopc_consistent_lookup set col = 9 where col_unique = 9", + "delete from twopc_consistent_lookup where id = 9", + "commit", + }, + logExpected: map[string][]string{ + "ks.redo_statement:80-": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"delete from twopc_consistent_lookup where id = 9 limit 10001 /* INT64 */\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"delete from twopc_consistent_lookup where id = 9 limit 10001 /* INT64 */\")]", + }, + "ks.redo_statement:40-80": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"update twopc_consistent_lookup set col = 9 where col_unique = 9 limit 10001 /* INT64 */\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"update twopc_consistent_lookup set col = 9 where col_unique = 9 limit 10001 /* INT64 */\")]", + }, + "ks.twopc_consistent_lookup:-40": { + "insert:[INT64(20) INT64(4) INT64(22)]", + }, + "ks.twopc_consistent_lookup:40-80": { + "update:[INT64(6) INT64(9) INT64(9)]", + }, + "ks.twopc_consistent_lookup:80-": { + "delete:[INT64(9) INT64(4) INT64(4)]", + }, + "ks.consistent_lookup_unique:-40": { + "insert:[INT64(22) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + "ks.consistent_lookup_unique:80-": { + "delete:[INT64(4) VARBINARY(\"\\x90\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + }, + "ks.consistent_lookup:80-": { + "insert:[INT64(4) INT64(20) VARBINARY(\"(\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "insert:[INT64(9) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) INT64(6) VARBINARY(\"`\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", + "delete:[INT64(4) INT64(9) VARBINARY(\"\\x90\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")]", }, }, }, diff --git a/go/test/endtoend/transaction/twopc/utils/utils.go b/go/test/endtoend/transaction/twopc/utils/utils.go index 2bed39c2b87..a65fa03148b 100644 --- a/go/test/endtoend/transaction/twopc/utils/utils.go +++ b/go/test/endtoend/transaction/twopc/utils/utils.go @@ -44,7 +44,7 @@ const ( // ClearOutTable deletes everything from a table. Sometimes the table might have more rows than allowed in a single delete query, // so we have to do the deletions iteratively. -func ClearOutTable(t *testing.T, vtParams mysql.ConnParams, tableName string) { +func ClearOutTable(t testing.TB, vtParams mysql.ConnParams, tableName string) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() for { diff --git a/go/test/endtoend/transaction/twopc/vschema.json b/go/test/endtoend/transaction/twopc/vschema.json index 0c22f40d54b..e6bbbfdb9a4 100644 --- a/go/test/endtoend/transaction/twopc/vschema.json +++ b/go/test/endtoend/transaction/twopc/vschema.json @@ -24,6 +24,24 @@ "to": "keyspace_id" }, "owner": "twopc_lookup" + }, + "consistent_lookup_vdx": { + "type": "consistent_lookup", + "params": { + "table": "consistent_lookup", + "from": "col,id", + "to": "keyspace_id" + }, + "owner": "twopc_consistent_lookup" + }, + "consistent_lookup_unique_vdx": { + "type": "consistent_lookup_unique", + "params": { + "table": "consistent_lookup_unique", + "from": "col_unique", + "to": "keyspace_id" + }, + "owner": "twopc_consistent_lookup" } }, "tables": { @@ -85,6 +103,41 @@ "name": "xxhash" } ] + }, + "twopc_consistent_lookup": { + "column_vindexes": [ + { + "column": "id", + "name": "reverse_bits" + }, + { + "columns": [ + "col", + "id" + ], + "name": "consistent_lookup_vdx" + }, + { + "column": "col_unique", + "name": "consistent_lookup_unique_vdx" + } + ] + }, + "consistent_lookup": { + "column_vindexes": [ + { + "column": "col", + "name": "xxhash" + } + ] + }, + "consistent_lookup_unique": { + "column_vindexes": [ + { + "column": "col_unique", + "name": "xxhash" + } + ] } } } \ No newline at end of file diff --git a/go/test/endtoend/transaction/tx_test.go b/go/test/endtoend/transaction/tx_test.go index 753dcfb46bd..fd162cb3d41 100644 --- a/go/test/endtoend/transaction/tx_test.go +++ b/go/test/endtoend/transaction/tx_test.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) var ( @@ -46,7 +47,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -57,7 +57,6 @@ func TestMain(m *testing.M) { clusterInstance.VtgateGrpcPort = clusterInstance.GetAndReservePort() // Set extra tablet args for twopc clusterInstance.VtTabletExtraArgs = []string{ - "--twopc_enable", "--twopc_abandon_age", "3600", } @@ -71,7 +70,7 @@ func TestMain(m *testing.M) { Name: keyspaceName, SchemaSQL: SchemaSQL, VSchema: VSchema, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, false); err != nil { return 1, err @@ -95,7 +94,6 @@ func TestMain(m *testing.M) { // TestTransactionModes tests transactions using twopc mode func TestTransactionModes(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) @@ -141,7 +139,6 @@ func TestTransactionModes(t *testing.T) { // TestTransactionIsolation tests transaction isolation level. func TestTransactionIsolation(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) @@ -248,6 +245,5 @@ func start(t *testing.T) func() { return func() { deleteAll() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/utils/cmp.go b/go/test/endtoend/utils/cmp.go index 3b47e1f68dc..b2e1eca03e9 100644 --- a/go/test/endtoend/utils/cmp.go +++ b/go/test/endtoend/utils/cmp.go @@ -215,6 +215,30 @@ func (mcmp *MySQLCompare) Exec(query string) *sqltypes.Result { return vtQr } +// ExecVitessAndMySQLDifferentQueries executes Vitess and MySQL with the queries provided. +func (mcmp *MySQLCompare) ExecVitessAndMySQLDifferentQueries(vtQ, mQ string) *sqltypes.Result { + mcmp.t.Helper() + vtQr, err := mcmp.VtConn.ExecuteFetch(vtQ, 1000, true) + require.NoError(mcmp.t, err, "[Vitess Error] for query: "+vtQ) + + mysqlQr, err := mcmp.MySQLConn.ExecuteFetch(mQ, 1000, true) + require.NoError(mcmp.t, err, "[MySQL Error] for query: "+mQ) + compareVitessAndMySQLResults(mcmp.t, vtQ, mcmp.VtConn, vtQr, mysqlQr, CompareOptions{}) + return vtQr +} + +// ExecAssert is the same as Exec, but it only does assertions, it won't FailNow +func (mcmp *MySQLCompare) ExecAssert(query string) *sqltypes.Result { + mcmp.t.Helper() + vtQr, err := mcmp.VtConn.ExecuteFetch(query, 1000, true) + assert.NoError(mcmp.t, err, "[Vitess Error] for query: "+query) + + mysqlQr, err := mcmp.MySQLConn.ExecuteFetch(query, 1000, true) + assert.NoError(mcmp.t, err, "[MySQL Error] for query: "+query) + compareVitessAndMySQLResults(mcmp.t, query, mcmp.VtConn, vtQr, mysqlQr, CompareOptions{}) + return vtQr +} + // ExecNoCompare executes the query on vitess and mysql but does not compare the result with each other. func (mcmp *MySQLCompare) ExecNoCompare(query string) (*sqltypes.Result, *sqltypes.Result) { mcmp.t.Helper() @@ -301,3 +325,10 @@ func (mcmp *MySQLCompare) ExecAllowError(query string) (*sqltypes.Result, error) } return vtQr, vtErr } + +func (mcmp *MySQLCompare) VExplain(query string) string { + mcmp.t.Helper() + vtQr, vtErr := mcmp.VtConn.ExecuteFetch("vexplain plan "+query, 1, true) + require.NoError(mcmp.t, vtErr, "[Vitess Error] for query: "+query) + return vtQr.Rows[0][0].ToString() +} diff --git a/go/test/endtoend/utils/mysql_test.go b/go/test/endtoend/utils/mysql_test.go index 41b74583f69..4d3d992e879 100644 --- a/go/test/endtoend/utils/mysql_test.go +++ b/go/test/endtoend/utils/mysql_test.go @@ -50,7 +50,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) exitCode := func() int { clusterInstance = cluster.NewCluster(cell, "localhost") diff --git a/go/test/endtoend/utils/mysqlvsvitess/main_test.go b/go/test/endtoend/utils/mysqlvsvitess/main_test.go index 8f162fae41d..f064afb895d 100644 --- a/go/test/endtoend/utils/mysqlvsvitess/main_test.go +++ b/go/test/endtoend/utils/mysqlvsvitess/main_test.go @@ -64,7 +64,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) exitCode := func() int { clusterInstance = cluster.NewCluster(cell, "localhost") diff --git a/go/test/endtoend/utils/utils.go b/go/test/endtoend/utils/utils.go index 35404981164..baa82821306 100644 --- a/go/test/endtoend/utils/utils.go +++ b/go/test/endtoend/utils/utils.go @@ -32,6 +32,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/vt/vtgate/engine" ) // AssertContains ensures the given query result contains the expected results. @@ -160,6 +161,19 @@ func Exec(t testing.TB, conn *mysql.Conn, query string) *sqltypes.Result { return qr } +// ExecTrace executes the given query with trace using the given connection. The trace result is returned. +// The test fails if the query produces an error. +func ExecTrace(t testing.TB, conn *mysql.Conn, query string) engine.PrimitiveDescription { + t.Helper() + qr, err := conn.ExecuteFetch(fmt.Sprintf("vexplain trace %s", query), 10000, false) + require.NoError(t, err, "for query: "+query) + + // Extract the trace result and format it with indentation for pretty printing + pd, err := engine.PrimitiveDescriptionFromString(qr.Rows[0][0].ToString()) + require.NoError(t, err) + return pd +} + // ExecMulti executes the given (potential multi) queries using the given connection. // The test fails if any of the queries produces an error func ExecMulti(t testing.TB, conn *mysql.Conn, query string) error { diff --git a/go/test/endtoend/vault/vault_test.go b/go/test/endtoend/vault/vault_test.go index f8e19c07a0c..f1ffbf75357 100644 --- a/go/test/endtoend/vault/vault_test.go +++ b/go/test/endtoend/vault/vault_test.go @@ -99,7 +99,6 @@ var ( ) func TestVaultAuth(t *testing.T) { - defer cluster.PanicHandler(nil) // Instantiate Vitess Cluster objects and start topo initializeClusterEarly(t) @@ -244,7 +243,7 @@ func initializeClusterLate(t *testing.T) { err := clusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard}) require.NoError(t, err) - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TopoPort, "localhost", clusterInstance.TmpDirectory) out, err := vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync") require.NoError(t, err, out) diff --git a/go/test/endtoend/versionupgrade/upgrade_test.go b/go/test/endtoend/versionupgrade/upgrade_test.go index 181b5dfc9ad..48e552c3a7c 100644 --- a/go/test/endtoend/versionupgrade/upgrade_test.go +++ b/go/test/endtoend/versionupgrade/upgrade_test.go @@ -72,7 +72,6 @@ var ( // TestMain is the main entry point func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -131,12 +130,10 @@ func TestMain(m *testing.M) { } func TestShards(t *testing.T) { - defer cluster.PanicHandler(t) assert.Equal(t, 2, len(clusterInstance.Keyspaces[0].Shards)) } func TestDeploySchema(t *testing.T) { - defer cluster.PanicHandler(t) if clusterInstance.ReusingVTDATAROOT { // we assume data is already deployed @@ -163,7 +160,6 @@ func TestDeploySchema(t *testing.T) { } func TestTablesExist(t *testing.T) { - defer cluster.PanicHandler(t) checkTables(t, "", totalTableCount) } diff --git a/go/test/endtoend/vreplication/cluster_test.go b/go/test/endtoend/vreplication/cluster_test.go index dc5a72e5e88..bcf50d43702 100644 --- a/go/test/endtoend/vreplication/cluster_test.go +++ b/go/test/endtoend/vreplication/cluster_test.go @@ -109,8 +109,6 @@ type VitessCluster struct { Cells map[string]*Cell Topo *cluster.TopoProcess Vtctld *cluster.VtctldProcess - Vtctl *cluster.VtctlProcess - VtctlClient *cluster.VtctlClientProcess VtctldClient *cluster.VtctldClientProcess VTOrcProcess *cluster.VTOrcProcess } @@ -166,13 +164,12 @@ func (vc *VitessCluster) StartVTOrc() error { if vc.VTOrcProcess != nil { return nil } - base := cluster.VtctlProcessInstance(vc.ClusterConfig.topoPort, vc.ClusterConfig.hostname) - base.Binary = "vtorc" + base := cluster.VtProcessInstance("vtorc", "vtorc", vc.ClusterConfig.topoPort, vc.ClusterConfig.hostname) vtorcProcess := &cluster.VTOrcProcess{ - VtctlProcess: *base, - LogDir: vc.ClusterConfig.tmpDir, - Config: cluster.VTOrcConfiguration{}, - Port: vc.ClusterConfig.vtorcPort, + VtProcess: base, + LogDir: vc.ClusterConfig.tmpDir, + Config: cluster.VTOrcConfiguration{}, + Port: vc.ClusterConfig.vtorcPort, } err := vtorcProcess.Setup() if err != nil { @@ -385,8 +382,6 @@ func NewVitessCluster(t *testing.T, opts *clusterOptions) *VitessCluster { } vc.setupVtctld() - vc.setupVtctl() - vc.setupVtctlClient() vc.setupVtctldClient() return vc @@ -400,27 +395,17 @@ func (vc *VitessCluster) setupVtctld() { vc.Vtctld.Setup(vc.CellNames[0], extraVtctldArgs...) } -func (vc *VitessCluster) setupVtctl() { - vc.Vtctl = cluster.VtctlProcessInstance(vc.ClusterConfig.topoPort, vc.ClusterConfig.hostname) - require.NotNil(vc.t, vc.Vtctl) +func (vc *VitessCluster) setupVtctldClient() { + vc.VtctldClient = cluster.VtctldClientProcessInstance(vc.ClusterConfig.vtctldGrpcPort, vc.ClusterConfig.topoPort, vc.ClusterConfig.hostname, vc.ClusterConfig.tmpDir) + require.NotNil(vc.t, vc.VtctldClient) for _, cellName := range vc.CellNames { - vc.Vtctl.AddCellInfo(cellName) + vc.VtctldClient.AddCellInfo(cellName) cell, err := vc.AddCell(vc.t, cellName) require.NoError(vc.t, err) require.NotNil(vc.t, cell) } } -func (vc *VitessCluster) setupVtctlClient() { - vc.VtctlClient = cluster.VtctlClientProcessInstance(vc.ClusterConfig.hostname, vc.Vtctld.GrpcPort, vc.ClusterConfig.tmpDir) - require.NotNil(vc.t, vc.VtctlClient) -} - -func (vc *VitessCluster) setupVtctldClient() { - vc.VtctldClient = cluster.VtctldClientProcessInstance(vc.ClusterConfig.hostname, vc.Vtctld.GrpcPort, vc.ClusterConfig.tmpDir) - require.NotNil(vc.t, vc.VtctldClient) -} - // CleanupDataroot deletes the vtdataroot directory. Since we run multiple tests sequentially in a single CI test shard, // we can run out of disk space due to all the leftover artifacts from previous tests. func (vc *VitessCluster) CleanupDataroot(t *testing.T, recreate bool) { @@ -461,7 +446,7 @@ func (vc *VitessCluster) AddKeyspace(t *testing.T, cells []*Cell, ksName string, SidecarDBName: sidecarDBName, } - err := vc.VtctldClient.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName) + err := vc.VtctldClient.CreateKeyspace(keyspace.Name, keyspace.SidecarDBName, "") require.NoError(t, err) log.Infof("Applying throttler config for keyspace %s", keyspace.Name) @@ -486,17 +471,17 @@ func (vc *VitessCluster) AddKeyspace(t *testing.T, cells []*Cell, ksName string, require.NoError(t, vc.AddShards(t, cells, keyspace, shards, numReplicas, numRdonly, tabletIDBase, opts)) if schema != "" { - err := vc.VtctlClient.ApplySchema(ksName, schema) + err := vc.VtctldClient.ApplySchema(ksName, schema) require.NoError(t, err) } keyspace.Schema = schema if vschema != "" { - err := vc.VtctlClient.ApplyVSchema(ksName, vschema) + err := vc.VtctldClient.ApplyVSchema(ksName, vschema) require.NoError(t, err) } keyspace.VSchema = vschema - err = vc.VtctlClient.ExecuteCommand("RebuildKeyspaceGraph", ksName) + err = vc.VtctldClient.ExecuteCommand("RebuildKeyspaceGraph", ksName) require.NoError(t, err) return keyspace, nil } @@ -585,7 +570,7 @@ func (vc *VitessCluster) AddShards(t *testing.T, cells []*Cell, keyspace *Keyspa log.Infof("Shard %s already exists, not adding", shardName) } else { log.Infof("Adding Shard %s", shardName) - if err := vc.VtctlClient.ExecuteCommand("CreateShard", keyspace.Name+"/"+shardName); err != nil { + if err := vc.VtctldClient.ExecuteCommand("CreateShard", keyspace.Name+"/"+shardName); err != nil { t.Fatalf("CreateShard command failed with %+v\n", err) } keyspace.Shards[shardName] = shard @@ -684,7 +669,7 @@ func (vc *VitessCluster) AddShards(t *testing.T, cells []*Cell, keyspace *Keyspa } require.NotEqual(t, 0, primaryTabletUID, "Should have created a primary tablet") log.Infof("InitializeShard and make %d primary", primaryTabletUID) - require.NoError(t, vc.VtctlClient.InitializeShard(keyspace.Name, shardName, cells[0].Name, primaryTabletUID)) + require.NoError(t, vc.VtctldClient.InitializeShard(keyspace.Name, shardName, cells[0].Name, primaryTabletUID)) log.Infof("Finished creating shard %s", shard.Name) } @@ -721,7 +706,7 @@ func (vc *VitessCluster) AddShards(t *testing.T, cells []*Cell, keyspace *Keyspa } } - err := vc.VtctlClient.ExecuteCommand("RebuildKeyspaceGraph", keyspace.Name) + err := vc.VtctldClient.ExecuteCommand("RebuildKeyspaceGraph", keyspace.Name) require.NoError(t, err) log.Infof("Waiting for throttler config to be applied on all shards") @@ -750,7 +735,7 @@ func (vc *VitessCluster) DeleteShard(t testing.TB, cellName string, ksName strin } log.Infof("Deleting Shard %s", shardName) // TODO how can we avoid the use of even_if_serving? - if output, err := vc.VtctlClient.ExecuteCommandWithOutput("DeleteShard", "--", "--recursive", "--even_if_serving", ksName+"/"+shardName); err != nil { + if output, err := vc.VtctldClient.ExecuteCommandWithOutput("DeleteShard", "--recursive", "--even-if-serving", ksName+"/"+shardName); err != nil { t.Fatalf("DeleteShard command failed with error %+v and output %s\n", err, output) } diff --git a/go/test/endtoend/vreplication/config_test.go b/go/test/endtoend/vreplication/config_test.go index 4b4bcfecc35..b856572ab7b 100644 --- a/go/test/endtoend/vreplication/config_test.go +++ b/go/test/endtoend/vreplication/config_test.go @@ -29,7 +29,7 @@ import ( // 1. Composite or multi-column primary keys // 2. PKs that contain an ENUM column // 3. That we properly handle tables with auto_increment columns (which are stripped by default when -// moving the table to a sharded keyspace with vtctldclient and left in place when using vtctlclient) +// moving the table to a sharded keyspace) // // The Lead and Lead-1 tables also allows us to test several things: // 1. Mixed case identifiers @@ -45,12 +45,18 @@ import ( // default collation as it has to work across versions and the 8.0 default does not exist in 5.7. var ( // All standard user tables should have a primary key and at least one secondary key. - customerTypes = []string{"'individual'", "'soho'", "'enterprise'"} + customerTypes = []string{"'individual'", "'soho'", "'enterprise'"} + customerTableTemplate = `create table customer(cid int auto_increment, name varchar(128) collate utf8mb4_bin, meta json default null, + industryCategory varchar(100) generated always as (json_extract(meta, _utf8mb4'$.industry')) virtual, typ enum(%s), + sport set('football','cricket','baseball'), ts timestamp not null default current_timestamp, bits bit(2) default b'11', date1 datetime not null default '0000-00-00 00:00:00', + date2 datetime not null default '2021-00-01 00:00:00', dec80 decimal(8,0), blb blob, primary key(%s), key(name)) CHARSET=utf8mb4` + customerTable = fmt.Sprintf(customerTableTemplate, strings.Join(customerTypes, ","), "cid,typ" /* PK columns */) + // customerTableModifiedPK has a PK on (cid) vs (cid,typ). + customerTableModifiedPK = fmt.Sprintf(customerTableTemplate, strings.Join(customerTypes, ","), "cid" /* PK columns */) + initialProductSchema = fmt.Sprintf(` create table product(pid int, description varbinary(128), date1 datetime not null default '0000-00-00 00:00:00', date2 datetime not null default '2021-00-01 00:00:00', primary key(pid), key(date1,date2)) CHARSET=utf8mb4; -create table customer(cid int auto_increment, name varchar(128) collate utf8mb4_bin, meta json default null, industryCategory varchar(100) generated always as (json_extract(meta, _utf8mb4'$.industry')) virtual, - typ enum(%s), sport set('football','cricket','baseball'), ts timestamp not null default current_timestamp, bits bit(2) default b'11', date1 datetime not null default '0000-00-00 00:00:00', - date2 datetime not null default '2021-00-01 00:00:00', dec80 decimal(8,0), blb blob, primary key(cid,typ), key(name)) CHARSET=utf8mb4; +%s; create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; create table merchant(mname varchar(128), category varchar(128), primary key(mname), key(category)) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; create table orders(oid int, cid int, pid int, mname varchar(128), price int, qty int, total int as (qty * price), total2 int as (qty * price) stored, primary key(oid), key(pid), key(cid)) CHARSET=utf8; @@ -69,7 +75,8 @@ create table `+"`blüb_tbl`"+` (id int, val1 varchar(20), `+"`blöb1`"+` blob, create table reftable (id int, val1 varchar(20), primary key(id), key(val1)); create table loadtest (id int, name varchar(256), primary key(id), key(name)); create table nopk (name varchar(128), age int unsigned); -`, strings.Join(customerTypes, ",")) +`, customerTable) + // These should always be ignored in vreplication internalSchema = ` create table _1e275eef_3b20_11eb_a38f_04ed332e05c2_20201210204529_gho(id int, val varbinary(128), primary key(id)); diff --git a/go/test/endtoend/vreplication/fk_ext_test.go b/go/test/endtoend/vreplication/fk_ext_test.go index e17247ab46b..d6716bcbf2d 100644 --- a/go/test/endtoend/vreplication/fk_ext_test.go +++ b/go/test/endtoend/vreplication/fk_ext_test.go @@ -151,8 +151,7 @@ func TestFKExt(t *testing.T) { } sqls := strings.Split(FKExtSourceSchema, "\n") for _, sql := range sqls { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ApplySchema", "--", - "--ddl_strategy=direct", "--sql", sql, keyspaceName) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ApplySchema", "--ddl-strategy=direct", "--sql", sql, keyspaceName) require.NoErrorf(t, err, output) } doReshard(t, fkextConfig.target2KeyspaceName, "reshard2to3", "-80,80-", threeShards, tablets) @@ -165,8 +164,7 @@ func TestFKExt(t *testing.T) { tablets[shard] = vc.Cells[cellName].Keyspaces[keyspaceName].Shards[shard].Tablets[fmt.Sprintf("%s-%d", cellName, tabletID)].Vttablet sqls := strings.Split(FKExtSourceSchema, "\n") for _, sql := range sqls { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ApplySchema", "--", - "--ddl_strategy=direct", "--sql", sql, keyspaceName) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ApplySchema", "--ddl-strategy=direct", "--sql", sql, keyspaceName) require.NoErrorf(t, err, output) } doReshard(t, fkextConfig.target2KeyspaceName, "reshard3to1", threeShards, "0", tablets) @@ -254,7 +252,7 @@ func doReshard(t *testing.T, keyspace, workflowName, sourceShards, targetShards for _, targetTab := range targetTabs { catchup(t, targetTab, workflowName, "Reshard") } - vdiff(t, keyspace, workflowName, fkextConfig.cell, false, true, nil) + vdiff(t, keyspace, workflowName, fkextConfig.cell, nil) rs.SwitchReadsAndWrites() //if lg.WaitForAdditionalRows(100) != nil { // t.Fatal("WaitForAdditionalRows failed") @@ -263,7 +261,7 @@ func doReshard(t *testing.T, keyspace, workflowName, sourceShards, targetShards if compareRowCounts(t, keyspace, strings.Split(sourceShards, ","), strings.Split(targetShards, ",")) != nil { t.Fatal("Row counts do not match") } - vdiff(t, keyspace, workflowName+"_reverse", fkextConfig.cell, true, false, nil) + vdiff(t, keyspace, workflowName+"_reverse", fkextConfig.cell, nil) rs.ReverseReadsAndWrites() //if lg.WaitForAdditionalRows(100) != nil { @@ -273,7 +271,7 @@ func doReshard(t *testing.T, keyspace, workflowName, sourceShards, targetShards if compareRowCounts(t, keyspace, strings.Split(targetShards, ","), strings.Split(sourceShards, ",")) != nil { t.Fatal("Row counts do not match") } - vdiff(t, keyspace, workflowName, fkextConfig.cell, false, true, nil) + vdiff(t, keyspace, workflowName, fkextConfig.cell, nil) lg.Stop() rs.SwitchReadsAndWrites() @@ -313,12 +311,10 @@ const fkExtMaterializeSpec = ` func materializeTables(t *testing.T) { wfName := "mat" - err := vc.VtctlClient.ExecuteCommand("ApplySchema", "--", "--ddl_strategy=direct", - "--sql", FKExtMaterializeSchema, fkextConfig.target1KeyspaceName) + err := vc.VtctldClient.ExecuteCommand("ApplySchema", "--ddl-strategy=direct", "--sql", FKExtMaterializeSchema, fkextConfig.target1KeyspaceName) require.NoError(t, err, fmt.Sprintf("ApplySchema Error: %s", err)) materializeSpec := fmt.Sprintf(fkExtMaterializeSpec, "mat", fkextConfig.target2KeyspaceName, fkextConfig.target1KeyspaceName) - err = vc.VtctlClient.ExecuteCommand("Materialize", materializeSpec) - require.NoError(t, err, "Materialize") + materialize(t, materializeSpec) tab := vc.getPrimaryTablet(t, fkextConfig.target1KeyspaceName, "0") catchup(t, tab, wfName, "Materialize") validateMaterializeRowCounts(t) @@ -363,7 +359,7 @@ func doMoveTables(t *testing.T, sourceKeyspace, targetKeyspace, workflowName, ta for _, targetTab := range targetTabs { catchup(t, targetTab, workflowName, "MoveTables") } - vdiff(t, targetKeyspace, workflowName, fkextConfig.cell, false, true, nil) + vdiff(t, targetKeyspace, workflowName, fkextConfig.cell, nil) lg.Stop() lg.SetDBStrategy("vtgate", targetKeyspace) if lg.Start() != nil { @@ -377,7 +373,7 @@ func doMoveTables(t *testing.T, sourceKeyspace, targetKeyspace, workflowName, ta } waitForLowLag(t, sourceKeyspace, workflowName+"_reverse") - vdiff(t, sourceKeyspace, workflowName+"_reverse", fkextConfig.cell, false, true, nil) + vdiff(t, sourceKeyspace, workflowName+"_reverse", fkextConfig.cell, nil) if lg.WaitForAdditionalRows(100) != nil { t.Fatal("WaitForAdditionalRows failed") } @@ -388,7 +384,7 @@ func doMoveTables(t *testing.T, sourceKeyspace, targetKeyspace, workflowName, ta } waitForLowLag(t, targetKeyspace, workflowName) time.Sleep(5 * time.Second) - vdiff(t, targetKeyspace, workflowName, fkextConfig.cell, false, true, nil) + vdiff(t, targetKeyspace, workflowName, fkextConfig.cell, nil) lg.Stop() mt.SwitchReadsAndWrites() mt.Complete() diff --git a/go/test/endtoend/vreplication/fk_test.go b/go/test/endtoend/vreplication/fk_test.go index f977d5a74cd..15664be51d9 100644 --- a/go/test/endtoend/vreplication/fk_test.go +++ b/go/test/endtoend/vreplication/fk_test.go @@ -102,11 +102,11 @@ func TestFKWorkflow(t *testing.T) { targetTab := targetKs.Shards["0"].Tablets[fmt.Sprintf("%s-%d", cellName, targetTabletId)].Vttablet require.NotNil(t, targetTab) catchup(t, targetTab, workflowName, "MoveTables") - vdiff(t, targetKeyspace, workflowName, cellName, true, false, nil) + vdiff(t, targetKeyspace, workflowName, cellName, nil) if withLoad { ls.waitForAdditionalRows(200) } - vdiff(t, targetKeyspace, workflowName, cellName, true, false, nil) + vdiff(t, targetKeyspace, workflowName, cellName, nil) if withLoad { cancel() <-ch diff --git a/go/test/endtoend/vreplication/global_routing_test.go b/go/test/endtoend/vreplication/global_routing_test.go new file mode 100644 index 00000000000..667c6352e2e --- /dev/null +++ b/go/test/endtoend/vreplication/global_routing_test.go @@ -0,0 +1,296 @@ +/* +Copyright 2025 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 vreplication + +import ( + "bytes" + "fmt" + "strings" + "testing" + "text/template" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + vttablet "vitess.io/vitess/go/vt/vttablet/common" +) + +type tgrTestConfig struct { + ksU1, ksU2, ksS1 string + ksU1Tables, ksU2Tables, ksS1Tables []string +} + +var grTestConfig = tgrTestConfig{ + ksU1: "unsharded1", + ksU2: "unsharded2", + ksS1: "sharded1", + ksU1Tables: []string{"t1", "t2", "t3"}, + ksU2Tables: []string{"t2", "t4", "t5"}, + ksS1Tables: []string{"t2", "t4", "t6"}, +} + +type grTestExpectations struct { + postKsU1, postKsU2, postKsS1 func(t *testing.T) +} + +// Scope helpers to this test file so we don't pollute the global namespace. +type grHelpers struct { + t *testing.T +} + +func (h *grHelpers) getSchema(tables []string) string { + var createSQL string + for _, table := range tables { + createSQL += fmt.Sprintf("CREATE TABLE %s (id int primary key, val varchar(32)) ENGINE=InnoDB;\n", table) + } + return createSQL +} + +func (h *grHelpers) getShardedVSchema(tables []string) string { + const vSchemaTmpl = `{ + "sharded": true, + "vindexes": { + "reverse_bits": { + "type": "reverse_bits" + } + }, + "tables": { + {{- range $i, $table := .Tables}} + {{- if gt $i 0}},{{end}} + "{{ $table }}": { + "column_vindexes": [ + { + "column": "id", + "name": "reverse_bits" + } + ] + } + {{- end}} + } +} +` + type VSchemaData struct { + Tables []string + } + tmpl, err := template.New("vschema").Parse(vSchemaTmpl) + require.NoError(h.t, err) + var buf bytes.Buffer + err = tmpl.Execute(&buf, VSchemaData{tables}) + require.NoError(h.t, err) + return buf.String() +} + +func (h *grHelpers) insertData(t *testing.T, keyspace string, table string, id int, val string) { + vtgateConn, cancel := getVTGateConn() + defer cancel() + _, err := vtgateConn.ExecuteFetch(fmt.Sprintf("insert into %s.%s(id, val) values(%d, '%s')", + keyspace, table, id, val), 1, false) + require.NoError(t, err) +} + +// There is a race between when a table is created and it is updated in the global table cache in vtgate. +// This function waits for the table to be available in vtgate before proceeding. +func (h *grHelpers) waitForTableAvailability(t *testing.T, vtgateConn *mysql.Conn, table string) { + timer := time.NewTimer(defaultTimeout) + defer timer.Stop() + for { + _, err := vtgateConn.ExecuteFetch(fmt.Sprintf("select * from %s", table), 1, false) + if err == nil || !strings.Contains(err.Error(), fmt.Sprintf("table %s not found", table)) { + return + } + select { + case <-timer.C: + require.FailNow(t, "timed out waiting for table availability for %s", table) + default: + time.Sleep(defaultTick) + } + } +} + +// Check for the expected global routing behavior for the given tables. Expected logic is implemented in the callback. +func (h *grHelpers) checkForTable( + t *testing.T, + tables []string, + queryCallback func(rs *sqltypes.Result, err error), +) { + vtgateConn, cancel := getVTGateConn() + defer cancel() + + for _, table := range tables { + for _, target := range []string{"", "@primary"} { + _, err := vtgateConn.ExecuteFetch(fmt.Sprintf("use %s", target), 1, false) + require.NoError(t, err) + h.waitForTableAvailability(t, vtgateConn, table) + rs, err := vtgateConn.ExecuteFetch(fmt.Sprintf("select * from %s", table), 1, false) + queryCallback(rs, err) + } + } +} + +func (h *grHelpers) isGlobal(t *testing.T, tables []string, expectedVal string) bool { + asExpected := true + + h.checkForTable(t, tables, func(rs *sqltypes.Result, err error) { + require.NoError(t, err) + gotVal := rs.Rows[0][1].ToString() + if gotVal != expectedVal { + asExpected = false + } + }) + + return asExpected +} + +func (h *grHelpers) isAmbiguous(t *testing.T, tables []string) bool { + asExpected := true + + h.checkForTable(t, tables, func(rs *sqltypes.Result, err error) { + if err == nil || !strings.Contains(err.Error(), "ambiguous") { + asExpected = false + } + }) + + return asExpected +} + +// getExpectations returns a map of expectations for global routing tests. The key is a boolean indicating whether +// the unsharded keyspace has a vschema. The value is a struct containing callbacks for verifying the global routing +// behavior after each keyspace is added. +func (h *grHelpers) getExpectations() *map[bool]*grTestExpectations { + var exp = make(map[bool]*grTestExpectations) + exp[false] = &grTestExpectations{ + postKsU1: func(t *testing.T) { + require.True(t, h.isGlobal(t, []string{"t1", "t2", "t3"}, grTestConfig.ksU1)) + }, + postKsU2: func(t *testing.T) { + require.True(t, h.isGlobal(t, []string{"t1", "t3"}, grTestConfig.ksU1)) + require.True(t, h.isGlobal(t, []string{"t4", "t5"}, grTestConfig.ksU2)) + require.True(t, h.isAmbiguous(t, []string{"t2"})) + }, + postKsS1: func(t *testing.T) { + require.True(t, h.isGlobal(t, []string{"t2", "t4"}, grTestConfig.ksS1)) + require.True(t, h.isGlobal(t, []string{"t1", "t3"}, grTestConfig.ksU1)) + require.True(t, h.isGlobal(t, []string{"t5"}, grTestConfig.ksU2)) + require.True(t, h.isGlobal(t, []string{"t6"}, grTestConfig.ksS1)) + }, + } + exp[true] = &grTestExpectations{ + postKsU1: func(t *testing.T) { + require.True(t, h.isGlobal(t, []string{"t1", "t2", "t3"}, grTestConfig.ksU1)) + }, + postKsU2: func(t *testing.T) { + require.True(t, h.isGlobal(t, []string{"t1", "t3"}, grTestConfig.ksU1)) + require.True(t, h.isGlobal(t, []string{"t4", "t5"}, grTestConfig.ksU2)) + require.True(t, h.isAmbiguous(t, []string{"t2"})) + }, + postKsS1: func(t *testing.T) { + require.True(t, h.isAmbiguous(t, []string{"t2", "t4"})) + require.True(t, h.isGlobal(t, []string{"t1", "t3"}, grTestConfig.ksU1)) + require.True(t, h.isGlobal(t, []string{"t5"}, grTestConfig.ksU2)) + }, + } + return &exp +} + +func (h *grHelpers) getUnshardedVschema(unshardedHasVSchema bool, tables []string) string { + if !unshardedHasVSchema { + return "" + } + vschema := `{"tables": {` + for i, table := range tables { + if i != 0 { + vschema += `,` + } + vschema += fmt.Sprintf(`"%s": {}`, table) + } + vschema += `}}` + return vschema +} + +func (h *grHelpers) rebuildGraphs(t *testing.T, keyspaces []string) { + var err error + for _, ks := range keyspaces { + err = vc.VtctldClient.ExecuteCommand("RebuildKeyspaceGraph", ks) + require.NoError(t, err) + } + require.NoError(t, err) + err = vc.VtctldClient.ExecuteCommand("RebuildVSchemaGraph") + require.NoError(t, err) +} + +// TestGlobalRouting tests global routing for unsharded and sharded keyspaces by setting up keyspaces +// with different table configurations and verifying that the tables are globally routed +// by querying via vtgate. +func TestGlobalRouting(t *testing.T) { + h := grHelpers{t} + exp := *h.getExpectations() + for unshardedHasVSchema, funcs := range exp { + require.NotNil(t, funcs) + testGlobalRouting(t, unshardedHasVSchema, funcs) + } +} + +func testGlobalRouting(t *testing.T, unshardedHasVSchema bool, funcs *grTestExpectations) { + h := grHelpers{t: t} + setSidecarDBName("_vt") + vttablet.InitVReplicationConfigDefaults() + + vc = NewVitessCluster(t, nil) + defer vc.TearDown() + zone1 := vc.Cells["zone1"] + config := grTestConfig + vc.AddKeyspace(t, []*Cell{zone1}, config.ksU1, "0", h.getUnshardedVschema(unshardedHasVSchema, config.ksU1Tables), + h.getSchema(config.ksU1Tables), 1, 0, 100, nil) + verifyClusterHealth(t, vc) + for _, table := range config.ksU1Tables { + h.insertData(t, config.ksU1, table, 1, config.ksU1) + vtgateConn, cancel := getVTGateConn() + waitForRowCount(t, vtgateConn, config.ksU1+"@replica", table, 1) + cancel() + } + keyspaces := []string{config.ksU1} + h.rebuildGraphs(t, keyspaces) + funcs.postKsU1(t) + + vc.AddKeyspace(t, []*Cell{zone1}, config.ksU2, "0", h.getUnshardedVschema(unshardedHasVSchema, config.ksU2Tables), + h.getSchema(config.ksU2Tables), 1, 0, 200, nil) + verifyClusterHealth(t, vc) + for _, table := range config.ksU2Tables { + h.insertData(t, config.ksU2, table, 1, config.ksU2) + vtgateConn, cancel := getVTGateConn() + waitForRowCount(t, vtgateConn, config.ksU2+"@replica", table, 1) + cancel() + } + keyspaces = append(keyspaces, config.ksU2) + h.rebuildGraphs(t, keyspaces) + funcs.postKsU2(t) + + vc.AddKeyspace(t, []*Cell{zone1}, config.ksS1, "-80,80-", h.getShardedVSchema(config.ksS1Tables), h.getSchema(config.ksS1Tables), + 1, 0, 300, nil) + verifyClusterHealth(t, vc) + for _, table := range config.ksS1Tables { + h.insertData(t, config.ksS1, table, 1, config.ksS1) + vtgateConn, cancel := getVTGateConn() + waitForRowCount(t, vtgateConn, config.ksS1+"@replica", table, 1) + cancel() + } + keyspaces = append(keyspaces, config.ksS1) + h.rebuildGraphs(t, keyspaces) + funcs.postKsS1(t) +} diff --git a/go/test/endtoend/vreplication/helper_test.go b/go/test/endtoend/vreplication/helper_test.go index ec2ce2da4d1..b3c55becc4a 100644 --- a/go/test/endtoend/vreplication/helper_test.go +++ b/go/test/endtoend/vreplication/helper_test.go @@ -362,52 +362,53 @@ func assertQueryDoesNotExecutesOnTablet(t *testing.T, conn *mysql.Conn, tablet * } func waitForWorkflowToBeCreated(t *testing.T, vc *VitessCluster, ksWorkflow string) { + keyspace, workflow := parseKeyspaceWorkflow(t, ksWorkflow) require.NoError(t, waitForCondition("workflow to be created", func() bool { - _, err := vc.VtctlClient.ExecuteCommandWithOutput("Workflow", ksWorkflow, "show") - return err == nil + output, err := vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", keyspace, "show", "--workflow", workflow, "--compact", "--include-logs=false") + return err == nil && !isEmptyWorkflowShowOutput(output) }, defaultTimeout)) } // waitForWorkflowState waits for all of the given workflow's // streams to reach the provided state. You can pass optional // key value pairs of the form "key==value" to also wait for -// additional stream sub-state such as "Message==for vdiff". +// additional stream sub-state such as "message==for vdiff". // Invalid checks are ignored. func waitForWorkflowState(t *testing.T, vc *VitessCluster, ksWorkflow string, wantState string, fieldEqualityChecks ...string) { + keyspace, workflow := parseKeyspaceWorkflow(t, ksWorkflow) done := false timer := time.NewTimer(workflowStateTimeout) + defer timer.Stop() log.Infof("Waiting for workflow %q to fully reach %q state", ksWorkflow, wantState) for { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("Workflow", ksWorkflow, "show") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", keyspace, "show", "--workflow", workflow, "--compact", "--include-logs=false") require.NoError(t, err, output) done = true state := "" - result := gjson.Get(output, "ShardStatuses") - result.ForEach(func(tabletId, tabletStreams gjson.Result) bool { // for each participating tablet - tabletStreams.ForEach(func(streamId, streamInfos gjson.Result) bool { // for each stream - if streamId.String() == "PrimaryReplicationStatuses" { - streamInfos.ForEach(func(attributeKey, attributeValue gjson.Result) bool { // for each attribute in the stream - // we need to wait for all streams to have the desired state - state = attributeValue.Get("State").String() - if state == wantState { - for i := 0; i < len(fieldEqualityChecks); i++ { - if kvparts := strings.Split(fieldEqualityChecks[i], "=="); len(kvparts) == 2 { - key := kvparts[0] - val := kvparts[1] - res := attributeValue.Get(key).String() - if !strings.EqualFold(res, val) { - done = false - } - } - } - if wantState == binlogdatapb.VReplicationWorkflowState_Running.String() && attributeValue.Get("Pos").String() == "" { + shardStreams := gjson.Get(output, "workflows.0.shard_streams") + // We need to wait for all streams in all shard streams to have the desired state. + shardStreams.ForEach(func(shardStreamId, shardStream gjson.Result) bool { + streams := shardStream.Get("*") + streams.ForEach(func(streamId, stream gjson.Result) bool { + info := stream.Map() + state = info["state"].String() + if state == wantState { + for i := 0; i < len(fieldEqualityChecks); i++ { + if kvparts := strings.Split(fieldEqualityChecks[i], "=="); len(kvparts) == 2 { + key := kvparts[0] + val := kvparts[1] + res := info[key].String() + if !strings.EqualFold(res, val) { done = false } - } else { - done = false } - return true - }) + } + if wantState == binlogdatapb.VReplicationWorkflowState_Running.String() && + (info["position"].Exists() && info["position"].String() == "") { + done = false + } + } else { + done = false } return true }) @@ -438,7 +439,8 @@ func waitForWorkflowState(t *testing.T, vc *VitessCluster, ksWorkflow string, wa // were re-added by the time the workflow hits the running phase. // For a Reshard workflow, where no tables are specified, pass // an empty string for the tables and all tables in the target -// keyspace will be checked. +// keyspace will be checked. It checks for the expected state until +// the timeout is reached. func confirmTablesHaveSecondaryKeys(t *testing.T, tablets []*cluster.VttabletProcess, ksName string, tables string) { require.NotNil(t, tablets) require.NotNil(t, tablets[0]) @@ -455,36 +457,52 @@ func confirmTablesHaveSecondaryKeys(t *testing.T, tablets []*cluster.VttabletPro tableArr = append(tableArr, row[0].ToString()) } } - for _, tablet := range tablets { - // Be sure that the schema is up to date. - err := vc.VtctldClient.ExecuteCommand("ReloadSchema", topoproto.TabletAliasString(&topodatapb.TabletAlias{ - Cell: tablet.Cell, - Uid: uint32(tablet.TabletUID), - })) - require.NoError(t, err) - for _, table := range tableArr { - if schema.IsInternalOperationTableName(table) { - continue - } - table := strings.TrimSpace(table) - secondaryKeys := 0 - res, err := tablet.QueryTablet(fmt.Sprintf("show create table %s", sqlescape.EscapeID(table)), ksName, true) - require.NoError(t, err) - require.NotNil(t, res) - row := res.Named().Row() - tableSchema := row["Create Table"].ToString() - parsedDDL, err := sqlparser.NewTestParser().ParseStrictDDL(tableSchema) + timer := time.NewTimer(defaultTimeout) + defer timer.Stop() + for { + tablesWithoutSecondaryKeys := make([]string, 0) + for _, tablet := range tablets { + // Be sure that the schema is up to date. + err := vc.VtctldClient.ExecuteCommand("ReloadSchema", topoproto.TabletAliasString(&topodatapb.TabletAlias{ + Cell: tablet.Cell, + Uid: uint32(tablet.TabletUID), + })) require.NoError(t, err) - createTable, ok := parsedDDL.(*sqlparser.CreateTable) - require.True(t, ok) - require.NotNil(t, createTable) - require.NotNil(t, createTable.GetTableSpec()) - for _, index := range createTable.GetTableSpec().Indexes { - if index.Info.Type != sqlparser.IndexTypePrimary { - secondaryKeys++ + for _, table := range tableArr { + if schema.IsInternalOperationTableName(table) { + continue + } + table := strings.TrimSpace(table) + secondaryKeys := 0 + res, err := tablet.QueryTablet(fmt.Sprintf("show create table %s", sqlescape.EscapeID(table)), ksName, true) + require.NoError(t, err) + require.NotNil(t, res) + row := res.Named().Row() + tableSchema := row["Create Table"].ToString() + parsedDDL, err := sqlparser.NewTestParser().ParseStrictDDL(tableSchema) + require.NoError(t, err) + createTable, ok := parsedDDL.(*sqlparser.CreateTable) + require.True(t, ok) + require.NotNil(t, createTable) + require.NotNil(t, createTable.GetTableSpec()) + for _, index := range createTable.GetTableSpec().Indexes { + if index.Info.Type != sqlparser.IndexTypePrimary { + secondaryKeys++ + } + } + if secondaryKeys == 0 { + tablesWithoutSecondaryKeys = append(tablesWithoutSecondaryKeys, table) } } - require.Greater(t, secondaryKeys, 0, "Table %s does not have any secondary keys", table) + } + if len(tablesWithoutSecondaryKeys) == 0 { + return + } + select { + case <-timer.C: + require.FailNow(t, "The following table(s) do not have any secondary keys: %s", strings.Join(tablesWithoutSecondaryKeys, ", ")) + default: + time.Sleep(defaultTick) } } } @@ -527,7 +545,7 @@ func validateDryRunResults(t *testing.T, output string, want []string) { gotDryRun := strings.Split(output, "\n") require.True(t, len(gotDryRun) > 3) var startRow int - if strings.HasPrefix(gotDryRun[1], "Parameters:") { // vtctlclient + if strings.HasPrefix(gotDryRun[1], "Parameters:") { // vtctldclient startRow = 3 } else if strings.Contains(gotDryRun[0], "deprecated") { startRow = 4 @@ -565,7 +583,7 @@ func checkIfTableExists(t *testing.T, vc *VitessCluster, tabletAlias string, tab var err error found := false - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("GetSchema", "--", "--tables", table, tabletAlias); err != nil { + if output, err = vc.VtctldClient.ExecuteCommandWithOutput("GetSchema", "--tables", table, tabletAlias); err != nil { return false, err } jsonparser.ArrayEach([]byte(output), func(value []byte, dataType jsonparser.ValueType, offset int, err error) { @@ -588,19 +606,10 @@ func validateTableInDenyList(t *testing.T, vc *VitessCluster, ksShard string, ta } func isTableInDenyList(t *testing.T, vc *VitessCluster, ksShard string, table string) (bool, error) { - var output string - var err error - found := false - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("GetShard", ksShard); err != nil { - 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) { - if string(value) == table { - found = true - } - }, "tablet_controls", "[0]", "denied_tables") - return found, nil + output, err := vc.VtctldClient.ExecuteCommandWithOutput("GetShard", ksShard) + require.NoError(t, err, "GetShard error", "%v %v", err, output) + deniedTable := gjson.Get(output, fmt.Sprintf("shard.tablet_controls.0.denied_tables.#(==\"%s\"", table)) + return deniedTable.Exists(), nil } // expectNumberOfStreams waits for the given number of streams to be present and @@ -626,7 +635,7 @@ func confirmAllStreamsRunning(t *testing.T, vtgateConn *mysql.Conn, database str func printShardPositions(vc *VitessCluster, ksShards []string) { for _, ksShard := range ksShards { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ShardReplicationPositions", ksShard) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ShardReplicationPositions", ksShard) if err != nil { fmt.Printf("Error in ShardReplicationPositions: %v, output %v", err, output) } else { @@ -638,7 +647,7 @@ func printShardPositions(vc *VitessCluster, ksShards []string) { func printRoutingRules(t *testing.T, vc *VitessCluster, msg string) error { var output string var err error - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("GetRoutingRules"); err != nil { + if output, err = vc.VtctldClient.ExecuteCommandWithOutput("GetRoutingRules", "--compact"); err != nil { return err } fmt.Printf("Routing Rules::%s:\n%s\n", msg, output) @@ -665,29 +674,22 @@ func getDebugVar(t *testing.T, port int, varPath []string) (string, error) { func confirmWorkflowHasCopiedNoData(t *testing.T, targetKS, workflow string) { timer := time.NewTimer(defaultTimeout) defer timer.Stop() - ksWorkflow := fmt.Sprintf("%s.%s", targetKS, workflow) for { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("Workflow", ksWorkflow, "show") - require.NoError(t, err) - result := gjson.Get(output, "ShardStatuses") - result.ForEach(func(tabletId, tabletStreams gjson.Result) bool { // for each source tablet - tabletStreams.ForEach(func(streamId, streamInfos gjson.Result) bool { // for each stream - if streamId.String() == "PrimaryReplicationStatuses" { - streamInfos.ForEach(func(attributeKey, attributeValue gjson.Result) bool { // for each attribute in the stream - state := attributeValue.Get("State").String() - pos := attributeValue.Get("Pos").String() - // If we've actually copied anything then we'll have a position in the stream - if (state == binlogdatapb.VReplicationWorkflowState_Running.String() || state == binlogdatapb.VReplicationWorkflowState_Copying.String()) && pos != "" { - require.FailNowf(t, "Unexpected data copied in workflow", - "The MoveTables workflow %q copied data in less than %s when it should have been waiting. Show output: %s", - ksWorkflow, defaultTimeout, output) - } - return true // end attribute loop - }) - } - return true // end stream loop - }) - return true // end tablet loop + output, err := vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", targetKs, "show", "--workflow", workflow, "--compact", "--include-logs=false") + require.NoError(t, err, output) + streams := gjson.Get(output, "workflows.0.shard_streams.*.streams") + streams.ForEach(func(streamId, stream gjson.Result) bool { // For each stream + info := stream.Map() + state := info["state"] + pos := info["position"] + // If we've actually copied anything then we'll have a position in the stream + if (state.Exists() && (state.String() == binlogdatapb.VReplicationWorkflowState_Running.String() || state.String() == binlogdatapb.VReplicationWorkflowState_Copying.String())) && + (pos.Exists() && pos.String() != "") { + require.FailNowf(t, "Unexpected data copied in workflow", + "The MoveTables workflow %q copied data in less than %s when it should have been waiting. Show output: %s", + ksWorkflow, defaultTimeout, output) + } + return true }) select { case <-timer.C: @@ -1088,3 +1090,21 @@ func validateOverrides(t *testing.T, tabs map[string]*cluster.VttabletProcess, w } } } + +func parseKeyspaceWorkflow(t *testing.T, ksWorkflow string) (string, string) { + t.Helper() + keyspace, workflow, ok := strings.Cut(ksWorkflow, ".") + require.True(t, ok, "invalid . value: %s", ksWorkflow) + return keyspace, workflow +} + +func isEmptyWorkflowShowOutput(output string) bool { + const ( + emptyJSON = `{}` + emptyNonCompactWorkflowShowResponse = `{ + "workflows": [] +}` + ) + v := strings.TrimSpace(output) + return v == emptyJSON || v == emptyNonCompactWorkflowShowResponse +} diff --git a/go/test/endtoend/vreplication/lookup_vindex_helper_test.go b/go/test/endtoend/vreplication/lookup_vindex_helper_test.go new file mode 100644 index 00000000000..359ecc1d21b --- /dev/null +++ b/go/test/endtoend/vreplication/lookup_vindex_helper_test.go @@ -0,0 +1,152 @@ +/* +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 vreplication + +import ( + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + + "vitess.io/vitess/go/vt/sqlparser" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +type lookupVindex struct { + typ string + name string + tableKeyspace string + table string + columns []string + ownerTable string + ownerTableKeyspace string + ignoreNulls bool + + t *testing.T +} + +func (lv *lookupVindex) String() string { + return lv.typ + " " + lv.name + " on " + lv.tableKeyspace + "." + lv.table + " (" + lv.columns[0] + ")" +} + +func (lv *lookupVindex) create() { + cols := strings.Join(lv.columns, ",") + args := []string{ + "LookupVindex", + "--name", lv.name, + "--table-keyspace=" + lv.ownerTableKeyspace, + "create", + "--keyspace=" + lv.tableKeyspace, + "--type=" + lv.typ, + "--table-owner=" + lv.ownerTable, + "--table-owner-columns=" + cols, + "--tablet-types=PRIMARY", + } + if lv.ignoreNulls { + args = append(args, "--ignore-nulls") + } + + err := vc.VtctldClient.ExecuteCommand(args...) + require.NoError(lv.t, err, "error executing LookupVindex create: %v", err) + waitForWorkflowState(lv.t, vc, fmt.Sprintf("%s.%s", lv.ownerTableKeyspace, lv.name), binlogdatapb.VReplicationWorkflowState_Running.String()) + lv.expectParamsAndOwner(true) +} + +func (lv *lookupVindex) cancel() { + args := []string{ + "LookupVindex", + "--name", lv.name, + "--table-keyspace=" + lv.ownerTableKeyspace, + "cancel", + } + err := vc.VtctldClient.ExecuteCommand(args...) + require.NoError(lv.t, err, "error executing LookupVindex complete: %v", err) +} + +func (lv *lookupVindex) externalize() { + args := []string{ + "LookupVindex", + "--name", lv.name, + "--table-keyspace=" + lv.ownerTableKeyspace, + "externalize", + "--keyspace=" + lv.tableKeyspace, + } + err := vc.VtctldClient.ExecuteCommand(args...) + require.NoError(lv.t, err, "error executing LookupVindex externalize: %v", err) + lv.expectParamsAndOwner(false) +} + +func (lv *lookupVindex) internalize() { + args := []string{ + "LookupVindex", + "--name", lv.name, + "--table-keyspace=" + lv.ownerTableKeyspace, + "internalize", + "--keyspace=" + lv.tableKeyspace, + } + err := vc.VtctldClient.ExecuteCommand(args...) + require.NoError(lv.t, err, "error executing LookupVindex internalize: %v", err) + lv.expectParamsAndOwner(true) +} + +func (lv *lookupVindex) complete() { + args := []string{ + "LookupVindex", + "--name", lv.name, + "--table-keyspace=" + lv.ownerTableKeyspace, + "complete", + "--keyspace=" + lv.tableKeyspace, + } + err := vc.VtctldClient.ExecuteCommand(args...) + require.NoError(lv.t, err, "error executing LookupVindex complete: %v", err) + lv.expectParamsAndOwner(false) +} + +func (lv *lookupVindex) show() error { + return nil +} + +func (lv *lookupVindex) expectParamsAndOwner(expectedWriteOnlyParam bool) { + vschema, err := vc.VtctldClient.ExecuteCommandWithOutput("GetVSchema", lv.ownerTableKeyspace) + require.NoError(lv.t, err, "error executing GetVSchema: %v", err) + vdx := gjson.Get(vschema, fmt.Sprintf("vindexes.%s", lv.name)) + require.NotNil(lv.t, vdx, "lookup vindex %s not found", lv.name) + + expectedOwner, expectedFrom, expectedTo := lv.ownerTable, strings.Join(lv.columns, ","), "keyspace_id" + require.Equal(lv.t, expectedOwner, vdx.Get("owner").String(), "expected 'owner' parameter to be %s", expectedOwner) + require.Equal(lv.t, expectedFrom, vdx.Get("params.from").String(), "expected 'from' parameter to be %s", expectedFrom) + require.Equal(lv.t, expectedTo, vdx.Get("params.to").String(), "expected 'to' parameter to be %s", expectedTo) + + want := "" + if expectedWriteOnlyParam { + want = "true" + } + require.Equal(lv.t, want, vdx.Get("params.write_only").String(), "expected write_only parameter to be %s", want) +} + +func getNumRowsInQuery(t *testing.T, query string) int { + stmt, err := sqlparser.NewTestParser().Parse(query) + require.NoError(t, err) + insertStmt, ok := stmt.(*sqlparser.Insert) + require.True(t, ok) + rows, ok := insertStmt.Rows.(sqlparser.Values) + require.True(t, ok) + return len(rows) +} diff --git a/go/test/endtoend/vreplication/lookup_vindex_test.go b/go/test/endtoend/vreplication/lookup_vindex_test.go new file mode 100644 index 00000000000..0e6810f3887 --- /dev/null +++ b/go/test/endtoend/vreplication/lookup_vindex_test.go @@ -0,0 +1,349 @@ +/* +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 vreplication + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/test/endtoend/cluster" + vttablet "vitess.io/vitess/go/vt/vttablet/common" +) + +type TestClusterSpec struct { + keyspaceName string + vschema string + schema string +} + +var lookupClusterSpec = TestClusterSpec{ + keyspaceName: "lookup", + vschema: ` +{ + "sharded": true, + "vindexes": { + "reverse_bits": { + "type": "reverse_bits" + } + }, + "tables": { + "t1": { + "column_vindexes": [ + { + "column": "c1", + "name": "reverse_bits" + } + ] + } + } +} +`, + schema: ` +create table t1( + c1 int, + c2 int, + val varchar(128), + primary key(c1) +); +`, +} + +func setupLookupVindexKeyspace(t *testing.T) map[string]*cluster.VttabletProcess { + tablets := make(map[string]*cluster.VttabletProcess) + if _, err := vc.AddKeyspace(t, []*Cell{vc.Cells["zone1"]}, lookupClusterSpec.keyspaceName, "-80,80-", + lookupClusterSpec.vschema, lookupClusterSpec.schema, defaultReplicas, defaultRdonly, 200, nil); err != nil { + require.NoError(t, err) + } + defaultCell := vc.Cells[vc.CellNames[0]] + ks := vc.Cells[defaultCell.Name].Keyspaces[lookupClusterSpec.keyspaceName] + targetTab1 = ks.Shards["-80"].Tablets["zone1-200"].Vttablet + targetTab2 = ks.Shards["80-"].Tablets["zone1-300"].Vttablet + tablets["-80"] = targetTab1 + tablets["80-"] = targetTab2 + return tablets +} + +type lookupTestCase struct { + name string + lv *lookupVindex + initQuery string + runningQuery string + postExternalizeQuery string + postInternalizeQuery string + postCompleteQuery string + cleanupQuery string +} + +func TestLookupVindex(t *testing.T) { + setSidecarDBName("_vt") + origDefaultReplicas := defaultReplicas + origDefaultRdonly := defaultRdonly + defer func() { + defaultReplicas = origDefaultReplicas + defaultRdonly = origDefaultRdonly + }() + defaultReplicas = 1 + defaultRdonly = 0 + vc = setupMinimalCluster(t) + defer vc.TearDown() + vttablet.InitVReplicationConfigDefaults() + + _ = setupLookupVindexKeyspace(t) + + initQuery := "insert into t1 (c1, c2, val) values (1, 1, 'val1'), (2, 2, 'val2'), (3, 3, 'val3')" + runningQuery := "insert into t1 (c1, c2, val) values (4, 4, 'val4'), (5, 5, 'val5'), (6, 6, 'val6')" + postExternalizeQuery := "insert into t1 (c1, c2, val) values (7, 7, 'val7'), (8, 8, 'val8'), (9, 9, 'val9')" + postInternalizeQuery := "insert into t1 (c1, c2, val) values (10, 10, 'val10'), (11, 11, 'val11'), (12, 12, 'val12')" + postCompleteQuery := "insert into t1 (c1, c2, val) values (13, 13, 'val13'), (14, 14, 'val14'), (15, 15, 'val15')" + cleanupQuery := "delete from t1" + + testCases := []lookupTestCase{ + { + name: "non-unique lookup index, one column", + lv: &lookupVindex{ + typ: "consistent_lookup", + name: "t1_c2_lookup", + tableKeyspace: lookupClusterSpec.keyspaceName, + table: "t1", + columns: []string{"c2"}, + ownerTable: "t1", + ownerTableKeyspace: lookupClusterSpec.keyspaceName, + ignoreNulls: true, + t: t, + }, + }, + { + name: "lookup index, two columns", + lv: &lookupVindex{ + typ: "lookup", + name: "t1_c2_val_lookup", + tableKeyspace: lookupClusterSpec.keyspaceName, + table: "t1", + columns: []string{"c2", "val"}, + ownerTable: "t1", + ownerTableKeyspace: lookupClusterSpec.keyspaceName, + ignoreNulls: true, + t: t, + }, + }, + { + name: "unique lookup index, one column", + lv: &lookupVindex{ + typ: "lookup_unique", + name: "t1_c2_unique_lookup", + tableKeyspace: lookupClusterSpec.keyspaceName, + table: "t1", + columns: []string{"c2"}, + ownerTable: "t1", + ownerTableKeyspace: lookupClusterSpec.keyspaceName, + ignoreNulls: true, + t: t, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tc.initQuery = initQuery + tc.runningQuery = runningQuery + tc.postExternalizeQuery = postExternalizeQuery + tc.postInternalizeQuery = postInternalizeQuery + tc.postCompleteQuery = postCompleteQuery + tc.cleanupQuery = cleanupQuery + testLookupVindex(t, &tc) + }) + } + + for _, tc := range testCases { + // Modify the testcase name, here we cancel just after creating lookupvindex. + tc.name = tc.name + ", cancel" + t.Run(tc.name, func(t *testing.T) { + // Modify the name to avoid error on duplicate lookup vindex/table name. + tc.lv.name = tc.lv.name + "_cancel" + + tc.initQuery = initQuery + tc.runningQuery = runningQuery + tc.postCompleteQuery = postCompleteQuery + tc.cleanupQuery = cleanupQuery + testLookupVindexCancel(t, &tc) + }) + } + + for _, tc := range testCases { + // Modify the testcase name, here we cancel just after externalizing lookupvindex. + tc.name = tc.name + ", externalize and cancel" + t.Run(tc.name, func(t *testing.T) { + // Modify the name to avoid error on duplicate lookup vindex/table name. + tc.lv.name = tc.lv.name + "_externalize_cancel" + + tc.initQuery = initQuery + tc.runningQuery = runningQuery + tc.postExternalizeQuery = postExternalizeQuery + tc.postCompleteQuery = postCompleteQuery + tc.cleanupQuery = cleanupQuery + testLookupVindexCancelAfterExternalize(t, &tc) + }) + } +} + +func testLookupVindex(t *testing.T, tc *lookupTestCase) { + vtgateConn, cancel := getVTGateConn() + defer cancel() + var totalRows int + lv := tc.lv + + t.Run("init data", func(t *testing.T) { + totalRows += getNumRowsInQuery(t, tc.initQuery) + _, err := vtgateConn.ExecuteFetch(tc.initQuery, 1000, false) + require.NoError(t, err) + }) + + t.Run("create", func(t *testing.T) { + tc.lv.create() + + lks := lv.tableKeyspace + vindexName := lv.name + waitForRowCount(t, vtgateConn, lks, vindexName, totalRows) + totalRows += getNumRowsInQuery(t, tc.runningQuery) + _, err := vtgateConn.ExecuteFetch(tc.runningQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("externalize", func(t *testing.T) { + tc.lv.externalize() + totalRows += getNumRowsInQuery(t, tc.postExternalizeQuery) + _, err := vtgateConn.ExecuteFetch(tc.postExternalizeQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("internalize", func(t *testing.T) { + tc.lv.internalize() + totalRows += getNumRowsInQuery(t, tc.postInternalizeQuery) + _, err := vtgateConn.ExecuteFetch(tc.postInternalizeQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("externalize after internalize", func(t *testing.T) { + tc.lv.externalize() + }) + + t.Run("complete", func(t *testing.T) { + tc.lv.complete() + totalRows += getNumRowsInQuery(t, tc.postCompleteQuery) + _, err := vtgateConn.ExecuteFetch(tc.postCompleteQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("cleanup", func(t *testing.T) { + _, err := vtgateConn.ExecuteFetch(tc.cleanupQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, 0) + }) +} + +func testLookupVindexCancel(t *testing.T, tc *lookupTestCase) { + vtgateConn, cancel := getVTGateConn() + defer cancel() + var totalRows int + lv := tc.lv + + t.Run("init data", func(t *testing.T) { + totalRows += getNumRowsInQuery(t, tc.initQuery) + _, err := vtgateConn.ExecuteFetch(tc.initQuery, 1000, false) + require.NoError(t, err) + }) + + t.Run("create", func(t *testing.T) { + tc.lv.create() + lks := lv.tableKeyspace + vindexName := lv.name + waitForRowCount(t, vtgateConn, lks, vindexName, totalRows) + totalRows += getNumRowsInQuery(t, tc.runningQuery) + _, err := vtgateConn.ExecuteFetch(tc.runningQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("cancel", func(t *testing.T) { + tc.lv.cancel() + // Expect true as we cancelled the LookupVindex before externalizing. + lv.expectParamsAndOwner(true) + totalRows += getNumRowsInQuery(t, tc.postCompleteQuery) + _, err := vtgateConn.ExecuteFetch(tc.postCompleteQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("cleanup", func(t *testing.T) { + _, err := vtgateConn.ExecuteFetch(tc.cleanupQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, 0) + }) +} + +func testLookupVindexCancelAfterExternalize(t *testing.T, tc *lookupTestCase) { + vtgateConn, cancel := getVTGateConn() + defer cancel() + var totalRows int + lv := tc.lv + + t.Run("init data", func(t *testing.T) { + totalRows += getNumRowsInQuery(t, tc.initQuery) + _, err := vtgateConn.ExecuteFetch(tc.initQuery, 1000, false) + require.NoError(t, err) + }) + + t.Run("create", func(t *testing.T) { + tc.lv.create() + lks := lv.tableKeyspace + vindexName := lv.name + waitForRowCount(t, vtgateConn, lks, vindexName, totalRows) + totalRows += getNumRowsInQuery(t, tc.runningQuery) + _, err := vtgateConn.ExecuteFetch(tc.runningQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("externalize", func(t *testing.T) { + tc.lv.externalize() + totalRows += getNumRowsInQuery(t, tc.postExternalizeQuery) + _, err := vtgateConn.ExecuteFetch(tc.postExternalizeQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("cancel", func(t *testing.T) { + tc.lv.cancel() + // Expect false as we cancelled the LookupVindex after externalizing. + lv.expectParamsAndOwner(false) + totalRows += getNumRowsInQuery(t, tc.postCompleteQuery) + _, err := vtgateConn.ExecuteFetch(tc.postCompleteQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, totalRows) + }) + + t.Run("cleanup", func(t *testing.T) { + _, err := vtgateConn.ExecuteFetch(tc.cleanupQuery, 1000, false) + require.NoError(t, err) + waitForRowCount(t, vtgateConn, tc.lv.ownerTableKeyspace, lv.name, 0) + }) +} diff --git a/go/test/endtoend/vreplication/materialize_test.go b/go/test/endtoend/vreplication/materialize_test.go index c62099a5894..9434de9d356 100644 --- a/go/test/endtoend/vreplication/materialize_test.go +++ b/go/test/endtoend/vreplication/materialize_test.go @@ -61,7 +61,7 @@ const smMaterializeSpec = `{"workflow": "wf1", "source_keyspace": "ks1", "target const initDataQuery = `insert into ks1.tx(id, typ, val) values (1, 1, 'abc'), (2, 1, 'def'), (3, 2, 'def'), (4, 2, 'abc'), (5, 3, 'def'), (6, 3, 'abc')` // testShardedMaterialize tests a materialize workflow for a sharded cluster (single shard) using comparison filters -func testShardedMaterialize(t *testing.T, useVtctldClient bool) { +func testShardedMaterialize(t *testing.T) { var err error vc = NewVitessCluster(t, nil) ks1 := "ks1" @@ -81,7 +81,7 @@ func testShardedMaterialize(t *testing.T, useVtctldClient bool) { verifyClusterHealth(t, vc) _, err = vtgateConn.ExecuteFetch(initDataQuery, 0, false) require.NoError(t, err) - materialize(t, smMaterializeSpec, useVtctldClient) + materialize(t, smMaterializeSpec) tab := vc.getPrimaryTablet(t, ks2, "0") catchup(t, tab, "wf1", "Materialize") @@ -169,7 +169,7 @@ DETERMINISTIC RETURN id * length(val); ` -func testMaterialize(t *testing.T, useVtctldClient bool) { +func testMaterialize(t *testing.T) { var err error vc = NewVitessCluster(t, nil) sourceKs := "source" @@ -199,7 +199,7 @@ func testMaterialize(t *testing.T, useVtctldClient bool) { testMaterializeWithNonExistentTable(t) - materialize(t, smMaterializeSpec2, useVtctldClient) + materialize(t, smMaterializeSpec2) catchup(t, ks2Primary, "wf1", "Materialize") // validate data after the copy phase @@ -219,21 +219,10 @@ func testMaterialize(t *testing.T, useVtctldClient bool) { // TestMaterialize runs all the individual materialize tests defined above. func TestMaterialize(t *testing.T) { t.Run("Materialize", func(t *testing.T) { - testMaterialize(t, false) + testMaterialize(t) }) t.Run("ShardedMaterialize", func(t *testing.T) { - testShardedMaterialize(t, false) - }) -} - -// TestMaterializeVtctldClient runs all the individual materialize tests -// defined above using vtctldclient instead of vtctlclient. -func TestMaterializeVtctldClient(t *testing.T) { - t.Run("Materialize", func(t *testing.T) { - testMaterialize(t, true) - }) - t.Run("ShardedMaterialize", func(t *testing.T) { - testShardedMaterialize(t, true) + testShardedMaterialize(t) }) } @@ -315,7 +304,7 @@ func TestReferenceTableMaterialize(t *testing.T) { waitForQueryResult(t, vtgateConn, "ks2:"+shard, "select id, id2 from ref2", `[[INT64(1) INT64(1)] [INT64(2) INT64(2)] [INT64(3) INT64(3)]]`) } - vdiff(t, "ks2", "wf1", defaultCellName, false, true, nil) + vdiff(t, "ks2", "wf1", defaultCellName, nil) queries := []string{ "update ks1.ref1 set val='xyz'", @@ -332,5 +321,5 @@ func TestReferenceTableMaterialize(t *testing.T) { waitForRowCount(t, vtgateConn, "ks2:"+shard, "ref1", 4) waitForRowCount(t, vtgateConn, "ks2:"+shard, "ref2", 4) } - vdiff(t, "ks2", "wf1", defaultCellName, false, true, nil) + vdiff(t, "ks2", "wf1", defaultCellName, nil) } diff --git a/go/test/endtoend/vreplication/migrate_test.go b/go/test/endtoend/vreplication/migrate_test.go index 2ccb3158fd9..ef20d953781 100644 --- a/go/test/endtoend/vreplication/migrate_test.go +++ b/go/test/endtoend/vreplication/migrate_test.go @@ -41,142 +41,18 @@ func insertInitialDataIntoExternalCluster(t *testing.T, conn *mysql.Conn) { }) } -// TestVtctlMigrate runs an e2e test for importing from an external cluster using the vtctl Mount and Migrate commands. -// We have an anti-pattern in Vitess: vt executables look for an environment variable VTDATAROOT for certain cluster parameters -// like the log directory when they are created. Until this test we just needed a single cluster for e2e tests. -// However now we need to create an external Vitess cluster. For this we need a different VTDATAROOT and -// hence the VTDATAROOT env variable gets overwritten. -// Each time we need to create vt processes in the "other" cluster we need to set the appropriate VTDATAROOT -func TestVtctlMigrate(t *testing.T) { +// TestMigrateUnsharded runs an e2e test for importing from an external cluster using the +// vtctldclient Mount and Migrate commands.We have an anti-pattern in Vitess: vt executables +// look for an environment variable VTDATAROOT for certain cluster parameters like the log +// directory when they are created. Until this test we just needed a single cluster for e2e +// tests. However now we need to create an external Vitess cluster. For this we need a +// different VTDATAROOT and hence the VTDATAROOT env variable gets overwritten. Each time +// we need to create vt processes in the "other" cluster we need to set the appropriate +// VTDATAROOT. +func TestMigrateUnsharded(t *testing.T) { vc = NewVitessCluster(t, nil) - - oldDefaultReplicas := defaultReplicas - oldDefaultRdonly := defaultRdonly - defaultReplicas = 0 - defaultRdonly = 0 - defer func() { - defaultReplicas = oldDefaultReplicas - defaultRdonly = oldDefaultRdonly - }() - defer vc.TearDown() - defaultCell := vc.Cells[vc.CellNames[0]] - _, err := vc.AddKeyspace(t, []*Cell{defaultCell}, "product", "0", initialProductVSchema, initialProductSchema, defaultReplicas, defaultRdonly, 100, nil) - require.NoError(t, err, "failed to create product keyspace") - vtgate := defaultCell.Vtgates[0] - require.NotNil(t, vtgate, "failed to get vtgate") - - vtgateConn := getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) - defer vtgateConn.Close() - verifyClusterHealth(t, vc) - insertInitialData(t) - t.Run("VStreamFrom", func(t *testing.T) { - testVStreamFrom(t, vtgate, "product", 2) - }) - - // create external cluster - extCell := "extcell1" - extVc := NewVitessCluster(t, &clusterOptions{cells: []string{"extcell1"}, clusterConfig: externalClusterConfig}) - defer extVc.TearDown() - - extCell2 := extVc.Cells[extCell] - extVc.AddKeyspace(t, []*Cell{extCell2}, "rating", "0", initialExternalVSchema, initialExternalSchema, 0, 0, 1000, nil) - extVtgate := extCell2.Vtgates[0] - require.NotNil(t, extVtgate) - - verifyClusterHealth(t, extVc) - extVtgateConn := getConnection(t, extVc.ClusterConfig.hostname, extVc.ClusterConfig.vtgateMySQLPort) - insertInitialDataIntoExternalCluster(t, extVtgateConn) - - var output, expected string - ksWorkflow := "product.e1" - - t.Run("mount external cluster", func(t *testing.T) { - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Mount", "--", "--type=vitess", "--topo_type=etcd2", - fmt.Sprintf("--topo_server=localhost:%d", extVc.ClusterConfig.topoPort), "--topo_root=/vitess/global", "ext1"); err != nil { - t.Fatalf("Mount command failed with %+v : %s\n", err, output) - } - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Mount", "--", "--type=vitess", "--list"); err != nil { - t.Fatalf("Mount command failed with %+v : %s\n", err, output) - } - expected = "ext1\n" - require.Equal(t, expected, output) - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Mount", "--", "--type=vitess", "--show", "ext1"); err != nil { - t.Fatalf("Mount command failed with %+v : %s\n", err, output) - } - expected = `{"ClusterName":"ext1","topo_config":{"topo_type":"etcd2","server":"localhost:12379","root":"/vitess/global"}}` + "\n" - require.Equal(t, expected, output) - }) - - t.Run("migrate from external cluster", func(t *testing.T) { - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Migrate", "--", "--all", "--cells=extcell1", - "--source=ext1.rating", "create", ksWorkflow); err != nil { - t.Fatalf("Migrate command failed with %+v : %s\n", err, output) - } - 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) - 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) - vdiffSideBySide(t, ksWorkflow, "extcell1") - - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Migrate", "complete", ksWorkflow); err != nil { - t.Fatalf("Migrate command failed with %+v : %s\n", err, output) - } - - expectNumberOfStreams(t, vtgateConn, "migrate", "e1", "product:0", 0) - }) - t.Run("cancel migrate workflow", func(t *testing.T) { - execVtgateQuery(t, vtgateConn, "product", "drop table review,rating") - - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Migrate", "--", "--all", "--auto_start=false", "--cells=extcell1", - "--source=ext1.rating", "create", ksWorkflow); err != nil { - t.Fatalf("Migrate command failed with %+v : %s\n", err, 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) - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Migrate", "cancel", ksWorkflow); err != nil { - t.Fatalf("Migrate command failed with %+v : %s\n", err, output) - } - expectNumberOfStreams(t, vtgateConn, "migrate", "e1", "product:0", 0) - var found bool - found, err = checkIfTableExists(t, vc, "zone1-100", "review") - require.NoError(t, err) - require.False(t, found) - found, err = checkIfTableExists(t, vc, "zone1-100", "rating") - require.NoError(t, err) - require.False(t, found) - }) - t.Run("unmount external cluster", func(t *testing.T) { - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Mount", "--", "--type=vitess", "--unmount", "ext1"); err != nil { - t.Fatalf("Mount command failed with %+v : %s\n", err, output) - } - - if output, err = vc.VtctlClient.ExecuteCommandWithOutput("Mount", "--", "--type=vitess", "--list"); err != nil { - t.Fatalf("Mount command failed with %+v : %s\n", err, output) - } - expected = "\n" - require.Equal(t, expected, output) - - output, err = vc.VtctlClient.ExecuteCommandWithOutput("Mount", "--", "--type=vitess", "--show", "ext1") - require.Errorf(t, err, "there is no vitess cluster named ext1") - }) -} - -// TestVtctldMigrate runs an e2e test for importing from an external cluster using the vtctld Mount and Migrate commands. -// We have an anti-pattern in Vitess: vt executables look for an environment variable VTDATAROOT for certain cluster parameters -// like the log directory when they are created. Until this test we just needed a single cluster for e2e tests. -// However now we need to create an external Vitess cluster. For this we need a different VTDATAROOT and -// hence the VTDATAROOT env variable gets overwritten. -// Each time we need to create vt processes in the "other" cluster we need to set the appropriate VTDATAROOT -func TestVtctldMigrateUnsharded(t *testing.T) { - vc = NewVitessCluster(t, nil) - oldDefaultReplicas := defaultReplicas oldDefaultRdonly := defaultRdonly defaultReplicas = 0 @@ -186,8 +62,6 @@ func TestVtctldMigrateUnsharded(t *testing.T) { defaultRdonly = oldDefaultRdonly }() - defer vc.TearDown() - defaultCell := vc.Cells[vc.CellNames[0]] _, err := vc.AddKeyspace(t, []*Cell{defaultCell}, "product", "0", initialProductVSchema, initialProductSchema, defaultReplicas, defaultRdonly, 100, nil) @@ -256,7 +130,7 @@ func TestVtctldMigrateUnsharded(t *testing.T) { execVtgateQuery(t, extVtgateConn, "rating", "insert into rating(gid, pid, rating) values(3, 1, 3);") waitForRowCountInTablet(t, targetPrimary, "product", "rating", 3) waitForRowCountInTablet(t, targetPrimary, "product", "review", 4) - vdiffSideBySide(t, ksWorkflow, "extcell1") + doVDiff(t, ksWorkflow, "extcell1") output, err = vc.VtctldClient.ExecuteCommandWithOutput("Migrate", "--target-keyspace", "product", "--workflow", "e1", "show") @@ -316,10 +190,10 @@ func TestVtctldMigrateUnsharded(t *testing.T) { }) } -// TestVtctldMigrate adds a test for a sharded cluster to validate a fix for a bug where the target keyspace name -// doesn't match that of the source cluster. The test migrates from a cluster with keyspace customer to an "external" -// cluster with keyspace rating. -func TestVtctldMigrateSharded(t *testing.T) { +// TestMigrateSharded adds a test for a sharded cluster to validate a fix for a bug where +// the target keyspace name doesn't match that of the source cluster. The test migrates +// from a cluster with keyspace customer to an "external" cluster with keyspace rating. +func TestMigrateSharded(t *testing.T) { setSidecarDBName("_vt") currentWorkflowType = binlogdatapb.VReplicationWorkflowType_MoveTables oldDefaultReplicas := defaultReplicas diff --git a/go/test/endtoend/vreplication/movetables_buffering_test.go b/go/test/endtoend/vreplication/movetables_buffering_test.go index 7ef75390fbc..da8b9d1f96b 100644 --- a/go/test/endtoend/vreplication/movetables_buffering_test.go +++ b/go/test/endtoend/vreplication/movetables_buffering_test.go @@ -39,7 +39,7 @@ func TestMoveTablesBuffering(t *testing.T) { catchup(t, targetTab1, workflowName, "MoveTables") catchup(t, targetTab2, workflowName, "MoveTables") - vdiff(t, targetKs, workflowName, "", false, true, nil) + vdiff(t, targetKs, workflowName, "", nil) waitForLowLag(t, "customer", workflowName) for i := 0; i < 10; i++ { tstWorkflowSwitchReadsAndWrites(t) diff --git a/go/test/endtoend/vreplication/multi_tenant_test.go b/go/test/endtoend/vreplication/multi_tenant_test.go index 6bceaeefc6e..2cd908b449f 100644 --- a/go/test/endtoend/vreplication/multi_tenant_test.go +++ b/go/test/endtoend/vreplication/multi_tenant_test.go @@ -91,7 +91,15 @@ type multiTenantMigration struct { } const ( - mtSchema = "create table t1(id int, tenant_id int, primary key(id, tenant_id)) Engine=InnoDB" + // The source/mt schema does not have the tenant_id column in the PK as adding a + // column to a table can be done as an INSTANT operation whereas modifying a table's + // PK requires a full table rebuild. So as a practical matter in production the + // source schema will likely have the tenant_id column, but NOT have it be part of + // the PK. + mtSchema = "create table t1(id int, tenant_id int, primary key(id)) Engine=InnoDB" + // The target/st schema must have the tenant_id column in the PK and the primary + // vindex. + stSchema = "create table t1(id int, tenant_id int, primary key(id, tenant_id)) Engine=InnoDB" mtVSchema = ` { "multi_tenant_spec": { @@ -127,7 +135,6 @@ const ( } } ` - stSchema = mtSchema stVSchema = ` { "tables": { @@ -229,7 +236,7 @@ func TestMultiTenantSimple(t *testing.T) { // Create again and run it to completion. createFunc() - vdiff(t, targetKeyspace, workflowName, defaultCellName, false, true, nil) + vdiff(t, targetKeyspace, workflowName, defaultCellName, nil) mt.SwitchReads() confirmOnlyReadsSwitched(t) @@ -389,7 +396,7 @@ func TestMultiTenantSharded(t *testing.T) { // Note: we cannot insert into the target keyspace since that is never routed to the source keyspace. lastIndex = insertRows(lastIndex, sourceKeyspace) waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKeyspace, mt.workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) - vdiff(t, targetKeyspace, workflowName, defaultCellName, false, true, nil) + vdiff(t, targetKeyspace, workflowName, defaultCellName, nil) mt.SwitchReadsAndWrites() // Note: here we have already switched, and we can insert into the target keyspace, and it should get reverse // replicated to the source keyspace. The source keyspace is routed to the target keyspace at this point. @@ -429,8 +436,11 @@ func (mtm *multiTenantMigration) insertSomeData(t *testing.T, tenantId int64, ke defer closeConn() idx := mtm.getLastID(tenantId) for i := idx + 1; i <= idx+numRows; i++ { + // The source table has a PK on id only, so we have to make the id value + // unique rather than relying on the combination of (id, tenant_id) for + // our uniqueness. execQueryWithRetry(t, vtgateConn, - fmt.Sprintf("insert into %s.t1(id, tenant_id) values(%d, %d)", keyspace, i, tenantId), queryTimeout) + fmt.Sprintf("insert into %s.t1(id, tenant_id) values(%d, %d)", keyspace, i+(tenantId*1e4), tenantId), queryTimeout) } mtm.setLastID(tenantId, idx+numRows) } @@ -586,7 +596,7 @@ func (mtm *multiTenantMigration) switchTraffic(tenantId int64) { mt := mtm.getActiveMoveTables(tenantId) ksWorkflow := fmt.Sprintf("%s.%s", mtm.targetKeyspace, mt.workflowName) waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) - vdiff(t, mt.targetKeyspace, mt.workflowName, defaultCellName, false, true, nil) + vdiff(t, mt.targetKeyspace, mt.workflowName, defaultCellName, nil) mtm.insertSomeData(t, tenantId, sourceKeyspaceName, numAdditionalRowsPerTenant) mt.SwitchReadsAndWrites() mtm.insertSomeData(t, tenantId, sourceKeyspaceName, numAdditionalRowsPerTenant) diff --git a/go/test/endtoend/vreplication/partial_movetables_seq_test.go b/go/test/endtoend/vreplication/partial_movetables_seq_test.go index eec304e0a4d..959a0169950 100644 --- a/go/test/endtoend/vreplication/partial_movetables_seq_test.go +++ b/go/test/endtoend/vreplication/partial_movetables_seq_test.go @@ -271,9 +271,7 @@ func (wf *workflow) complete() { // TestPartialMoveTablesWithSequences enhances TestPartialMoveTables by adding an unsharded keyspace which has a // sequence. This tests that the sequence is migrated correctly and that we can reverse traffic back to the source func TestPartialMoveTablesWithSequences(t *testing.T) { - origExtraVTGateArgs := extraVTGateArgs - extraVTGateArgs = append(extraVTGateArgs, []string{ "--enable-partial-keyspace-migration", "--schema_change_signal=false", @@ -356,8 +354,8 @@ func TestPartialMoveTablesWithSequences(t *testing.T) { vtgateConn, closeConn = getVTGateConn() defer closeConn() - t.Run("Confirm routing rules", func(t *testing.T) { + t.Run("Confirm routing rules", func(t *testing.T) { // Global routing rules should be in place with everything going to the source keyspace (customer). confirmGlobalRoutingToSource(t) @@ -410,7 +408,6 @@ func TestPartialMoveTablesWithSequences(t *testing.T) { defer vtgateConn.Close() t.Run("Validate shard and tablet type routing", func(t *testing.T) { - // No shard targeting _, err = vtgateConn.ExecuteFetch(shard80DashRoutedQuery, 0, false) require.Error(t, err) @@ -482,10 +479,10 @@ func TestPartialMoveTablesWithSequences(t *testing.T) { insertCustomers(t) - output, err = tc.vc.VtctlClient.ExecuteCommandWithOutput("Workflow", "seqTgt.seq", "show") + output, err = tc.vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", wfSeq.toKeyspace, "show", "--workflow", wfSeq.name) require.NoError(t, err) - output, err = tc.vc.VtctlClient.ExecuteCommandWithOutput("Workflow", "seqSrc.seq_reverse", "show") + output, err = tc.vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", wfSeq.fromKeyspace, "show", "--workflow", fmt.Sprintf("%s_reverse", wfSeq.name)) require.NoError(t, err) wfSeq.complete() @@ -501,21 +498,19 @@ func TestPartialMoveTablesWithSequences(t *testing.T) { err = tstWorkflowExec(t, "", reverseWf, "", reverseKs, "", workflowActionCancel, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) - output, err := tc.vc.VtctlClient.ExecuteCommandWithOutput("Workflow", fmt.Sprintf("%s.%s", reverseKs, reverseWf), "show") - require.Error(t, err) - require.Contains(t, output, "no streams found") + output, err := tc.vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", reverseKs, "show", "--workflow", reverseWf) + require.NoError(t, err) + require.True(t, isEmptyWorkflowShowOutput(output)) - // Delete the original workflow - originalKsWf := fmt.Sprintf("%s.%s", targetKs, wf) - _, err = tc.vc.VtctlClient.ExecuteCommandWithOutput("Workflow", originalKsWf, "delete") + // Be sure that we've deleted the original workflow. + _, _ = tc.vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", targetKs, "delete", "--workflow", wf) + output, err = tc.vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", targetKs, "show", "--workflow", wf) require.NoError(t, err) - output, err = tc.vc.VtctlClient.ExecuteCommandWithOutput("Workflow", originalKsWf, "show") - require.Error(t, err) - require.Contains(t, output, "no streams found") + require.True(t, isEmptyWorkflowShowOutput(output)) } // Confirm that the global routing rules are now gone. - output, err = tc.vc.VtctlClient.ExecuteCommandWithOutput("GetRoutingRules") + output, err = tc.vc.VtctldClient.ExecuteCommandWithOutput("GetRoutingRules", "--compact") require.NoError(t, err) require.Equal(t, emptyGlobalRoutingRules, output) @@ -564,7 +559,7 @@ func insertCustomers(t *testing.T) { } func confirmGlobalRoutingToSource(t *testing.T) { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("GetRoutingRules") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("GetRoutingRules", "--compact") require.NoError(t, err) result := gjson.Get(output, "rules") result.ForEach(func(attributeKey, attributeValue gjson.Result) bool { diff --git a/go/test/endtoend/vreplication/partial_movetables_test.go b/go/test/endtoend/vreplication/partial_movetables_test.go index 7ae8f83416d..09e80b19bd4 100644 --- a/go/test/endtoend/vreplication/partial_movetables_test.go +++ b/go/test/endtoend/vreplication/partial_movetables_test.go @@ -127,7 +127,7 @@ func testPartialMoveTablesBasic(t *testing.T, flavor workflowFlavor) { waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKeyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) catchup(t, targetTab80Dash, workflowName, "MoveTables") - vdiff(t, targetKeyspace, workflowName, defaultCellName, false, true, nil) + vdiff(t, targetKeyspace, workflowName, defaultCellName, nil) mt.SwitchReadsAndWrites() time.Sleep(loadTestBufferingWindowDuration + 1*time.Second) mt.Complete() @@ -190,7 +190,7 @@ func testPartialMoveTablesBasic(t *testing.T, flavor workflowFlavor) { } waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKeyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) catchup(t, targetTab80Dash, workflowName, "MoveTables") - vdiff(t, targetKeyspace, workflowName, defaultCellName, false, true, nil) + vdiff(t, targetKeyspace, workflowName, defaultCellName, nil) vtgateConn, closeConn := getVTGateConn() defer closeConn() @@ -199,7 +199,7 @@ func testPartialMoveTablesBasic(t *testing.T, flavor workflowFlavor) { waitForRowCount(t, vtgateConn, "customer2:80-", "customer", 2) // customer2: 80- confirmGlobalRoutingToSource := func() { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("GetRoutingRules") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("GetRoutingRules", "--compact") require.NoError(t, err) result := gjson.Get(output, "rules") result.ForEach(func(attributeKey, attributeValue gjson.Result) bool { @@ -307,9 +307,6 @@ func testPartialMoveTablesBasic(t *testing.T, flavor workflowFlavor) { require.Contains(t, err.Error(), "target: customer.-80.replica", "Query was routed to the target before partial SwitchTraffic") workflowExec := tstWorkflowExec - if flavor == workflowFlavorVtctl { - workflowExec = tstWorkflowExecVtctl - } // We cannot Complete a partial move tables at the moment because // it will find that all traffic has (obviously) not been switched. @@ -337,7 +334,7 @@ func testPartialMoveTablesBasic(t *testing.T, flavor workflowFlavor) { waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKeyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) catchup(t, targetTabDash80, workflowName, "MoveTables") - vdiff(t, targetKeyspace, workflowName, defaultCellName, false, true, nil) + vdiff(t, targetKeyspace, workflowName, defaultCellName, nil) mtDash80.SwitchReadsAndWrites() time.Sleep(loadTestBufferingWindowDuration + 1*time.Second) @@ -366,21 +363,19 @@ func testPartialMoveTablesBasic(t *testing.T, flavor workflowFlavor) { err = workflowExec(t, "", reverseWf, "", reverseKs, "", workflowActionCancel, "", "", "", opts) require.NoError(t, err) - output, err := vc.VtctlClient.ExecuteCommandWithOutput("Workflow", "--", "--shards", opts.shardSubset, fmt.Sprintf("%s.%s", reverseKs, reverseWf), "show") - require.Error(t, err) - require.Contains(t, output, "no streams found") - - // Delete the original workflow - originalKsWf := fmt.Sprintf("%s.%s", targetKs, wf) - _, err = vc.VtctlClient.ExecuteCommandWithOutput("Workflow", "--", "--shards", opts.shardSubset, originalKsWf, "delete") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", reverseKs, "show", "--workflow", reverseWf, "--shards", opts.shardSubset) require.NoError(t, err) - output, err = vc.VtctlClient.ExecuteCommandWithOutput("Workflow", "--", "--shards", opts.shardSubset, originalKsWf, "show") - require.Error(t, err) - require.Contains(t, output, "no streams found") + require.True(t, isEmptyWorkflowShowOutput(output)) + + // Be sure we've deleted the original workflow. + _, _ = vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", targetKs, "delete", "--workflow", wf, "--shards", opts.shardSubset) + output, err = vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", targetKs, "show", "--workflow", wf, "--shards", opts.shardSubset) + require.NoError(t, err, output) + require.True(t, isEmptyWorkflowShowOutput(output)) } // Confirm that the global routing rules are now gone. - output, err := vc.VtctlClient.ExecuteCommandWithOutput("GetRoutingRules") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("GetRoutingRules", "--compact") require.NoError(t, err) require.Equal(t, emptyGlobalRoutingRules, output) @@ -390,7 +385,6 @@ func testPartialMoveTablesBasic(t *testing.T, flavor workflowFlavor) { // TestPartialMoveTablesBasic tests partial move tables by moving each // customer shard -- -80,80- -- once a a time to customer2. -// We test with both the vtctlclient and vtctldclient flavors. func TestPartialMoveTablesBasic(t *testing.T) { currentWorkflowType = binlogdatapb.VReplicationWorkflowType_MoveTables testPartialMoveTablesBasic(t, workflowFlavorVtctld) diff --git a/go/test/endtoend/vreplication/reference_test.go b/go/test/endtoend/vreplication/reference_test.go index 8ff77de8708..efef799878b 100644 --- a/go/test/endtoend/vreplication/reference_test.go +++ b/go/test/endtoend/vreplication/reference_test.go @@ -119,8 +119,8 @@ func TestReferenceTableMaterializationAndRouting(t *testing.T) { require.NoError(t, err) vtgateConn.Close() - materialize(t, materializeCatSpec, false) - materialize(t, materializeMfgSpec, false) + materialize(t, materializeCatSpec) + materialize(t, materializeMfgSpec) tabDash80 := vc.getPrimaryTablet(t, sks, "-80") tab80Dash := vc.getPrimaryTablet(t, sks, "80-") diff --git a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go index 28ffc762ecd..a8f1996d0d9 100644 --- a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go +++ b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go @@ -89,7 +89,7 @@ func createReshardWorkflow(t *testing.T, sourceShards, targetShards string) erro confirmTablesHaveSecondaryKeys(t, []*cluster.VttabletProcess{targetTab1}, targetKs, "") catchup(t, targetTab1, workflowName, "Reshard") catchup(t, targetTab2, workflowName, "Reshard") - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") return nil } @@ -104,7 +104,7 @@ func createMoveTablesWorkflow(t *testing.T, tables string) { confirmTablesHaveSecondaryKeys(t, []*cluster.VttabletProcess{targetTab1}, targetKs, tables) catchup(t, targetTab1, workflowName, "MoveTables") catchup(t, targetTab2, workflowName, "MoveTables") - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") } func tstWorkflowAction(t *testing.T, action, tabletTypes, cells string) error { @@ -112,7 +112,7 @@ func tstWorkflowAction(t *testing.T, action, tabletTypes, cells string) error { } // tstWorkflowExec executes a MoveTables or Reshard workflow command using -// vtctldclient. If you need to use the legacy vtctlclient, use +// vtctldclient. // tstWorkflowExecVtctl instead. func tstWorkflowExec(t *testing.T, cells, workflow, sourceKs, targetKs, tables, action, tabletTypes, sourceShards, targetShards string, options *workflowExecOptions) error { @@ -181,74 +181,6 @@ func tstWorkflowExec(t *testing.T, cells, workflow, sourceKs, targetKs, tables, return nil } -// tstWorkflowExecVtctl executes a MoveTables or Reshard workflow command using -// vtctlclient. It should operate exactly the same way as tstWorkflowExec, but -// using the legacy client. -func tstWorkflowExecVtctl(t *testing.T, cells, workflow, sourceKs, targetKs, tables, action, tabletTypes, - sourceShards, targetShards string, options *workflowExecOptions) error { - - var args []string - if currentWorkflowType == binlogdatapb.VReplicationWorkflowType_MoveTables { - args = append(args, "MoveTables") - } else { - args = append(args, "Reshard") - } - - args = append(args, "--") - - if BypassLagCheck { - args = append(args, "--max_replication_lag_allowed=2542087h") - } - if options.atomicCopy { - args = append(args, "--atomic-copy") - } - switch action { - case workflowActionCreate: - if currentWorkflowType == binlogdatapb.VReplicationWorkflowType_MoveTables { - args = append(args, "--source", sourceKs) - if tables != "" { - args = append(args, "--tables", tables) - } else { - args = append(args, "--all") - } - if sourceShards != "" { - args = append(args, "--source_shards", sourceShards) - } - } else { - args = append(args, "--source_shards", sourceShards, "--target_shards", targetShards) - } - // Test new experimental --defer-secondary-keys flag - switch currentWorkflowType { - case binlogdatapb.VReplicationWorkflowType_MoveTables, binlogdatapb.VReplicationWorkflowType_Migrate, binlogdatapb.VReplicationWorkflowType_Reshard: - if !options.atomicCopy && options.deferSecondaryKeys { - args = append(args, "--defer-secondary-keys") - } - args = append(args, "--initialize-target-sequences") // Only used for MoveTables - } - case workflowActionMirrorTraffic: - args = append(args, "--percent", strconv.FormatFloat(float64(options.percent), byte('f'), -1, 32)) - default: - if options.shardSubset != "" { - args = append(args, "--shards", options.shardSubset) - } - } - if cells != "" { - args = append(args, "--cells", cells) - } - if tabletTypes != "" { - args = append(args, "--tablet_types", tabletTypes) - } - args = append(args, "--timeout", time.Minute.String()) - ksWorkflow := fmt.Sprintf("%s.%s", targetKs, workflow) - args = append(args, action, ksWorkflow) - output, err := vc.VtctlClient.ExecuteCommandWithOutput(args...) - lastOutput = output - if err != nil { - return fmt.Errorf("%s: %s", err, output) - } - return nil -} - func tstWorkflowSwitchReads(t *testing.T, tabletTypes, cells string) { if tabletTypes == "" { tabletTypes = "replica,rdonly" @@ -288,23 +220,15 @@ func tstWorkflowComplete(t *testing.T) error { } // testWorkflowUpdate is a very simple test of the workflow update -// vtctlclient/vtctldclient command. +// vtctldclient command. // It performs a non-behavior impacting update, setting tablet-types // to primary,replica,rdonly (the only applicable types in these tests). func testWorkflowUpdate(t *testing.T) { tabletTypes := "primary,replica,rdonly" - // Test vtctlclient first. - _, err := vc.VtctlClient.ExecuteCommandWithOutput("workflow", "--", "--tablet-types", tabletTypes, "noexist.noexist", "update") - require.Error(t, err, err) - resp, err := vc.VtctlClient.ExecuteCommandWithOutput("workflow", "--", "--tablet-types", tabletTypes, ksWorkflow, "update") - require.NoError(t, err) - require.NotEmpty(t, resp) - - // Test vtctldclient last. - _, err = vc.VtctldClient.ExecuteCommandWithOutput("workflow", "--keyspace", "noexist", "update", "--workflow", "noexist", "--tablet-types", tabletTypes) + _, err := vc.VtctldClient.ExecuteCommandWithOutput("workflow", "--keyspace", "noexist", "update", "--workflow", "noexist", "--tablet-types", tabletTypes) require.Error(t, err) // Change the tablet-types to rdonly. - resp, err = vc.VtctldClient.ExecuteCommandWithOutput("workflow", "--keyspace", targetKs, "update", "--workflow", workflowName, "--tablet-types", "rdonly") + resp, err := vc.VtctldClient.ExecuteCommandWithOutput("workflow", "--keyspace", targetKs, "update", "--workflow", workflowName, "--tablet-types", "rdonly") require.NoError(t, err, err) // Confirm that we changed the workflow. var ures vtctldatapb.WorkflowUpdateResponse @@ -559,10 +483,10 @@ func testReplicatingWithPKEnumCols(t *testing.T) { insertQuery := "insert into customer(cid, name, typ, sport, meta) values(2, 'Paül','soho','cricket',convert(x'7b7d' using utf8mb4))" execVtgateQuery(t, vtgateConn, sourceKs, deleteQuery) waitForNoWorkflowLag(t, vc, targetKs, workflowName) - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") execVtgateQuery(t, vtgateConn, sourceKs, insertQuery) waitForNoWorkflowLag(t, vc, targetKs, workflowName) - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") } func testReshardV2Workflow(t *testing.T) { @@ -697,9 +621,9 @@ func testMoveTablesV2Workflow(t *testing.T) { testRestOfWorkflow(t) // Create our primary intra-keyspace materialization. - materialize(t, materializeCustomerNameSpec, false) + materialize(t, materializeCustomerNameSpec) // Create a second one to confirm that multiple ones get migrated correctly. - materialize(t, materializeCustomerTypeSpec, false) + materialize(t, materializeCustomerTypeSpec) materializeShow() output, err = vc.VtctldClient.ExecuteCommandWithOutput(listAllArgs...) @@ -986,7 +910,7 @@ func moveCustomerTableSwitchFlows(t *testing.T, cells []*Cell, sourceCellOrAlias moveTablesAction(t, "Create", sourceCellOrAlias, workflow, sourceKs, targetKs, tables) catchup(t, targetTab1, workflow, workflowType) catchup(t, targetTab2, workflow, workflowType) - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") } allCellNames := getCellNames(cells) var switchReadsFollowedBySwitchWrites = func() { diff --git a/go/test/endtoend/vreplication/sidecardb_test.go b/go/test/endtoend/vreplication/sidecardb_test.go index be9ce67a626..f908d66a2ec 100644 --- a/go/test/endtoend/vreplication/sidecardb_test.go +++ b/go/test/endtoend/vreplication/sidecardb_test.go @@ -14,7 +14,7 @@ import ( const GetCurrentTablesQuery = "show tables from _vt" func getSidecarDBTables(t *testing.T, tabletID string) (numTablets int, tables []string) { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ExecuteFetchAsDba", "--", "--json", tabletID, GetCurrentTablesQuery) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ExecuteFetchAsDBA", "--json", tabletID, GetCurrentTablesQuery) require.NoError(t, err) result := gjson.Get(output, "rows") require.NotNil(t, result) @@ -51,7 +51,7 @@ func init() { } func prs(t *testing.T, keyspace, shard string) { - _, err := vc.VtctldClient.ExecuteCommandWithOutput("PlannedReparentShard", "--", fmt.Sprintf("%s/%s", keyspace, shard)) + _, err := vc.VtctldClient.ExecuteCommandWithOutput("PlannedReparentShard", fmt.Sprintf("%s/%s", keyspace, shard)) require.NoError(t, err) } @@ -118,7 +118,7 @@ func validateSidecarDBTables(t *testing.T, tabletID string, tables []string) { func modifySidecarDBSchema(t *testing.T, vc *VitessCluster, tabletID string, ddls []string) (numChanges int) { for _, ddl := range ddls { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ExecuteFetchAsDba", "--", tabletID, ddl) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ExecuteFetchAsDBA", tabletID, ddl) require.NoErrorf(t, err, output) } return len(ddls) diff --git a/go/test/endtoend/vreplication/time_zone_test.go b/go/test/endtoend/vreplication/time_zone_test.go index 2c0a9a4f5a5..3faa9e76a78 100644 --- a/go/test/endtoend/vreplication/time_zone_test.go +++ b/go/test/endtoend/vreplication/time_zone_test.go @@ -87,14 +87,13 @@ func TestMoveTablesTZ(t *testing.T) { tables := "datze" - ksErrorWorkflow := fmt.Sprintf("%s.%s", targetKs, "tzerr") - output, err := vc.VtctlClient.ExecuteCommandWithOutput("MoveTables", "--", "--source", sourceKs, "--tables", - tables, "--source_time_zone", "US/Pacifik", "Create", ksErrorWorkflow) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("MoveTables", "--workflow", workflow, "--target-keyspace", targetKs, "Create", + "--source-keyspace", sourceKs, "--tables", tables, "--source-time-zone", "US/Pacifik") require.Error(t, err, output) require.Contains(t, output, "time zone is invalid") - output, err = vc.VtctlClient.ExecuteCommandWithOutput("MoveTables", "--", "--source", sourceKs, "--tables", - tables, "--source_time_zone", "US/Pacific", "Create", ksWorkflow) + output, err = vc.VtctldClient.ExecuteCommandWithOutput("MoveTables", "--workflow", workflow, "--target-keyspace", targetKs, "Create", + "--source-keyspace", sourceKs, "--tables", tables, "--source-time-zone", "US/Pacific") require.NoError(t, err, output) catchup(t, customerTab, workflow, "MoveTables") @@ -105,7 +104,7 @@ func TestMoveTablesTZ(t *testing.T) { _, err = vtgateConn.ExecuteFetch("insert into datze(id, dt2) values (12, '2022-04-01 5:06:07')", 1, false) // dst require.NoError(t, err) - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") // update to test date conversions in replication (vplayer) mode (update statements) _, err = vtgateConn.ExecuteFetch("update datze set dt2 = '2022-04-01 5:06:07' where id = 11", 1, false) // dst @@ -113,7 +112,7 @@ func TestMoveTablesTZ(t *testing.T) { _, err = vtgateConn.ExecuteFetch("update datze set dt2 = '2022-01-01 10:20:30' where id = 12", 1, false) // standard time require.NoError(t, err) - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") query := "select * from datze" qrSourceUSPacific, err := productTab.QueryTablet(query, sourceKs, true) @@ -175,7 +174,7 @@ func TestMoveTablesTZ(t *testing.T) { require.Equal(t, row.AsString("dt2", ""), qrTargetUSPacific.Named().Rows[i].AsString("dt2", "")) require.Equal(t, row.AsString("ts1", ""), qrTargetUSPacific.Named().Rows[i].AsString("ts1", "")) } - output, err = vc.VtctlClient.ExecuteCommandWithOutput("MoveTables", "--", "SwitchTraffic", ksWorkflow) + output, err = vc.VtctldClient.ExecuteCommandWithOutput("MoveTables", "--target-keyspace", targetKs, "SwitchTraffic", "--workflow", workflow) require.NoError(t, err, output) qr, err := productTab.QueryTablet(sqlparser.BuildParsedQuery("select * from %s.vreplication where workflow='%s_reverse'", @@ -192,5 +191,5 @@ func TestMoveTablesTZ(t *testing.T) { // inserts to test date conversions in reverse replication execVtgateQuery(t, vtgateConn, "customer", "insert into datze(id, dt2) values (13, '2022-01-01 18:20:30')") execVtgateQuery(t, vtgateConn, "customer", "insert into datze(id, dt2) values (14, '2022-04-01 12:06:07')") - vdiffSideBySide(t, ksReverseWorkflow, "") + doVDiff(t, ksReverseWorkflow, "") } diff --git a/go/test/endtoend/vreplication/vdiff2_test.go b/go/test/endtoend/vreplication/vdiff2_test.go index 612ba00236b..c4bb2efc73a 100644 --- a/go/test/endtoend/vreplication/vdiff2_test.go +++ b/go/test/endtoend/vreplication/vdiff2_test.go @@ -175,6 +175,15 @@ func TestVDiff2(t *testing.T) { require.NoError(t, err) verifyClusterHealth(t, vc) + // Pre-create the customer table on the target keyspace, with the primary key on + // (cid) vs (cid,typ) on the source. This confirms that we are able to properly + // diff the table when the source and target have a different PK definition. + // Remove the 0 date restrictions as the customer table uses them in its DEFAULTs. + execVtgateQuery(t, vtgateConn, targetKs, "set @@session.sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'") + execVtgateQuery(t, vtgateConn, targetKs, customerTableModifiedPK) + // Set the sql_mode back to the default. + execVtgateQuery(t, vtgateConn, targetKs, "set @@session.sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'") + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { // Primary tablets for any new shards are added in the first cell. @@ -210,17 +219,19 @@ func testWorkflow(t *testing.T, vc *VitessCluster, tc *testCase, tks *Keyspace, statsShard := arrTargetShards[0] statsTablet := vc.getPrimaryTablet(t, tc.targetKs, statsShard) var args []string - args = append(args, tc.typ, "--") - args = append(args, "--source", tc.sourceKs) - if tc.typ == "Reshard" { - args = append(args, "--source_shards", tc.sourceShards, "--target_shards", tc.targetShards) - } + args = append(args, tc.typ) + args = append(args, "--workflow", tc.workflow) + args = append(args, "--target-keyspace", tc.targetKs) allCellNames := getCellNames(nil) + args = append(args, "create") args = append(args, "--cells", allCellNames) - args = append(args, "--tables", tc.tables) - args = append(args, "Create") - args = append(args, ksWorkflow) - err := vc.VtctlClient.ExecuteCommand(args...) + if tc.typ == "Reshard" { + args = append(args, "--source-shards", tc.sourceShards, "--target-shards", tc.targetShards) + } else { + args = append(args, "--source-keyspace", tc.sourceKs) + args = append(args, "--tables", tc.tables) + } + err := vc.VtctldClient.ExecuteCommand(args...) require.NoError(t, err) waitForShardsToCatchup := func() { @@ -279,8 +290,8 @@ func testWorkflow(t *testing.T, vc *VitessCluster, tc *testCase, tks *Keyspace, waitForShardsToCatchup() tc.vdiffCount++ // We only did vtctldclient vdiff create } else { - vdiff(t, tc.targetKs, tc.workflow, allCellNames, true, true, nil) - tc.vdiffCount += 2 // We did vtctlclient AND vtctldclient vdiff create + vdiff(t, tc.targetKs, tc.workflow, allCellNames, nil) + tc.vdiffCount++ } checkVDiffCountStat(t, statsTablet, tc.vdiffCount) @@ -288,7 +299,7 @@ func testWorkflow(t *testing.T, vc *VitessCluster, tc *testCase, tks *Keyspace, // compared by vdiff per table at the controller level -- works as expected. vdrc, err := getDebugVar(t, statsTablet.Port, []string{"VDiffRowsCompared"}) require.NoError(t, err, "failed to get VDiffRowsCompared stat from %s-%d tablet: %v", statsTablet.Cell, statsTablet.TabletUID, err) - uuid, jsout := performVDiff2Action(t, false, ksWorkflow, allCellNames, "show", "last", false, "--verbose") + uuid, jsout := performVDiff2Action(t, ksWorkflow, allCellNames, "show", "last", false, "--verbose") expect := gjson.Get(jsout, fmt.Sprintf("Reports.customer.%s", statsShard)).Int() got := gjson.Get(vdrc, fmt.Sprintf("%s.%s.%s", tc.workflow, uuid, "customer")).Int() require.Equal(t, expect, got, "expected VDiffRowsCompared stat to be %d, but got %d", expect, got) @@ -307,12 +318,12 @@ func testWorkflow(t *testing.T, vc *VitessCluster, tc *testCase, tks *Keyspace, if tc.stop { testStop(t, ksWorkflow, allCellNames) - tc.vdiffCount++ // We did either vtctlclient OR vtctldclient vdiff create + tc.vdiffCount++ } if tc.testCLICreateWait { testCLICreateWait(t, ksWorkflow, allCellNames) - tc.vdiffCount++ // We did either vtctlclient OR vtctldclient vdiff create + tc.vdiffCount++ } if tc.testCLIErrors { testCLIErrors(t, ksWorkflow, allCellNames) @@ -330,14 +341,14 @@ func testWorkflow(t *testing.T, vc *VitessCluster, tc *testCase, tks *Keyspace, // Create another VDiff record to confirm it gets deleted when the workflow is completed. ts := time.Now() - uuid, _ = performVDiff2Action(t, false, ksWorkflow, allCellNames, "create", "", false) - waitForVDiff2ToComplete(t, false, ksWorkflow, allCellNames, uuid, ts) + uuid, _ = performVDiff2Action(t, ksWorkflow, allCellNames, "create", "", false) + waitForVDiff2ToComplete(t, ksWorkflow, allCellNames, uuid, ts) tc.vdiffCount++ checkVDiffCountStat(t, statsTablet, tc.vdiffCount) - err = vc.VtctlClient.ExecuteCommand(tc.typ, "--", "SwitchTraffic", ksWorkflow) + err = vc.VtctldClient.ExecuteCommand(tc.typ, "--workflow", tc.workflow, "--target-keyspace", tc.targetKs, "SwitchTraffic") require.NoError(t, err) - err = vc.VtctlClient.ExecuteCommand(tc.typ, "--", "Complete", ksWorkflow) + err = vc.VtctldClient.ExecuteCommand(tc.typ, "--workflow", tc.workflow, "--target-keyspace", tc.targetKs, "Complete") require.NoError(t, err) // Confirm the VDiff data is deleted for the workflow. @@ -348,18 +359,18 @@ func testWorkflow(t *testing.T, vc *VitessCluster, tc *testCase, tks *Keyspace, func testCLIErrors(t *testing.T, ksWorkflow, cells string) { t.Run("Client error handling", func(t *testing.T) { - _, output := performVDiff2Action(t, false, ksWorkflow, cells, "badcmd", "", true) + _, output := performVDiff2Action(t, ksWorkflow, cells, "badcmd", "", true) require.Contains(t, output, "Usage:") - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "create", "invalid_uuid", true) + _, output = performVDiff2Action(t, ksWorkflow, cells, "create", "invalid_uuid", true) require.Contains(t, output, "invalid UUID provided") - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "resume", "invalid_uuid", true) + _, output = performVDiff2Action(t, ksWorkflow, cells, "resume", "invalid_uuid", true) require.Contains(t, output, "invalid UUID provided") - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "delete", "invalid_uuid", true) + _, output = performVDiff2Action(t, ksWorkflow, cells, "delete", "invalid_uuid", true) require.Contains(t, output, "invalid argument provided") - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "show", "invalid_uuid", true) + _, output = performVDiff2Action(t, ksWorkflow, cells, "show", "invalid_uuid", true) require.Contains(t, output, "invalid argument provided") - uuid, _ := performVDiff2Action(t, false, ksWorkflow, cells, "show", "last", false) - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "create", uuid, true) + uuid, _ := performVDiff2Action(t, ksWorkflow, cells, "show", "last", false) + _, output = performVDiff2Action(t, ksWorkflow, cells, "create", uuid, true) require.Contains(t, output, "already exists") }) } @@ -432,7 +443,7 @@ func testCLIFlagHandling(t *testing.T, targetKs, workflowName string, cell *Cell // Delete this vdiff as we used --auto-start=false and thus it never starts and // does not provide the normally expected show --verbose --format=json output. - _, output := performVDiff2Action(t, false, fmt.Sprintf("%s.%s", targetKs, workflowName), "", "delete", vduuid.String(), false) + _, output := performVDiff2Action(t, fmt.Sprintf("%s.%s", targetKs, workflowName), "", "delete", vduuid.String(), false) require.Equal(t, "completed", gjson.Get(output, "Status").String()) }) } @@ -450,35 +461,35 @@ func testDelete(t *testing.T, ksWorkflow, cells string) { } return int64(len(seen)) } - _, output := performVDiff2Action(t, false, ksWorkflow, cells, "show", "all", false) + _, output := performVDiff2Action(t, ksWorkflow, cells, "show", "all", false) initialVDiffCount := uuidCount(gjson.Get(output, "#.UUID").Array()) for ; initialVDiffCount < 3; initialVDiffCount++ { - _, _ = performVDiff2Action(t, false, ksWorkflow, cells, "create", "", false) + _, _ = performVDiff2Action(t, ksWorkflow, cells, "create", "", false) } // Now let's confirm that we have at least 3 unique VDiffs. - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "show", "all", false) + _, output = performVDiff2Action(t, ksWorkflow, cells, "show", "all", false) require.GreaterOrEqual(t, uuidCount(gjson.Get(output, "#.UUID").Array()), int64(3)) // And that our initial count is what we expect. require.Equal(t, initialVDiffCount, uuidCount(gjson.Get(output, "#.UUID").Array())) // Test show last with verbose too as a side effect. - uuid, output := performVDiff2Action(t, false, ksWorkflow, cells, "show", "last", false, "--verbose") + uuid, output := performVDiff2Action(t, ksWorkflow, cells, "show", "last", false, "--verbose") // The TableSummary is only present with --verbose. require.Contains(t, output, `"TableSummary":`) // Now let's delete one of the VDiffs. - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "delete", uuid, false) + _, output = performVDiff2Action(t, ksWorkflow, cells, "delete", uuid, false) require.Equal(t, "completed", gjson.Get(output, "Status").String()) // And confirm that our unique VDiff count has only decreased by one. - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "show", "all", false) + _, output = performVDiff2Action(t, ksWorkflow, cells, "show", "all", false) require.Equal(t, initialVDiffCount-1, uuidCount(gjson.Get(output, "#.UUID").Array())) // Now let's delete all of them. - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "delete", "all", false) + _, output = performVDiff2Action(t, ksWorkflow, cells, "delete", "all", false) require.Equal(t, "completed", gjson.Get(output, "Status").String()) // And finally confirm that we have no more VDiffs. - _, output = performVDiff2Action(t, false, ksWorkflow, cells, "show", "all", false) + _, output = performVDiff2Action(t, ksWorkflow, cells, "show", "all", false) require.Equal(t, int64(0), gjson.Get(output, "#").Int()) }) } @@ -502,7 +513,7 @@ func testResume(t *testing.T, tc *testCase, cells string) { ksWorkflow := fmt.Sprintf("%s.%s", tc.targetKs, tc.workflow) // Confirm the last VDiff is in the expected completed state. - uuid, output := performVDiff2Action(t, false, ksWorkflow, cells, "show", "last", false) + uuid, output := performVDiff2Action(t, ksWorkflow, cells, "show", "last", false) jsonOutput := getVDiffInfo(output) require.Equal(t, "completed", jsonOutput.State) // Save the number of rows compared in previous runs. @@ -518,8 +529,8 @@ func testResume(t *testing.T, tc *testCase, cells string) { // confirm that the VDiff was resumed, able to complete, and we compared the // expected number of rows in total (original run and resume) - _, _ = performVDiff2Action(t, false, ksWorkflow, cells, "resume", uuid, false) - info := waitForVDiff2ToComplete(t, false, ksWorkflow, cells, uuid, ogTime) + _, _ = performVDiff2Action(t, ksWorkflow, cells, "resume", uuid, false) + info := waitForVDiff2ToComplete(t, ksWorkflow, cells, uuid, ogTime) require.NotNil(t, info) require.False(t, info.HasMismatch) require.Equal(t, expectedRows, info.RowsCompared) @@ -529,10 +540,10 @@ 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. - uuid, _ := performVDiff2Action(t, false, ksWorkflow, cells, "create", "", false) - _, _ = performVDiff2Action(t, false, ksWorkflow, cells, "stop", uuid, false) + uuid, _ := performVDiff2Action(t, ksWorkflow, cells, "create", "", false) + _, _ = performVDiff2Action(t, ksWorkflow, cells, "stop", uuid, false) // Confirm the VDiff is in the expected state. - _, output := performVDiff2Action(t, false, ksWorkflow, cells, "show", uuid, false) + _, output := performVDiff2Action(t, ksWorkflow, cells, "show", uuid, false) jsonOutput := getVDiffInfo(output) // 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. @@ -549,7 +560,7 @@ func testAutoRetryError(t *testing.T, tc *testCase, cells string) { ksWorkflow := fmt.Sprintf("%s.%s", tc.targetKs, tc.workflow) // Confirm the last VDiff is in the expected completed state. - uuid, output := performVDiff2Action(t, false, ksWorkflow, cells, "show", "last", false) + uuid, output := performVDiff2Action(t, ksWorkflow, cells, "show", "last", false) jsonOutput := getVDiffInfo(output) require.Equal(t, "completed", jsonOutput.State) // Save the number of rows compared in the first run. @@ -576,7 +587,7 @@ func testAutoRetryError(t *testing.T, tc *testCase, cells string) { // Confirm that the VDiff was retried, able to complete, and we compared the expected // number of rows in total (original run and retry). - info := waitForVDiff2ToComplete(t, false, ksWorkflow, cells, uuid, ogTime) + info := waitForVDiff2ToComplete(t, ksWorkflow, cells, uuid, ogTime) require.NotNil(t, info) require.False(t, info.HasMismatch) require.Equal(t, expectedRows, info.RowsCompared) @@ -584,10 +595,10 @@ func testAutoRetryError(t *testing.T, tc *testCase, cells string) { } func testCLICreateWait(t *testing.T, ksWorkflow string, cells string) { - t.Run("vtctl create and wait", func(t *testing.T) { + t.Run("vtctldclient create and wait", func(t *testing.T) { chCompleted := make(chan bool) go func() { - _, output := performVDiff2Action(t, false, ksWorkflow, cells, "create", "", false, "--wait", "--wait-update-interval=1s") + _, output := performVDiff2Action(t, ksWorkflow, cells, "create", "", false, "--wait", "--wait-update-interval=1s") completed := false // We don't try to parse the JSON output as it may contain a series of outputs // that together do not form a valid JSON document. We can change this in the diff --git a/go/test/endtoend/vreplication/vdiff_helper_test.go b/go/test/endtoend/vreplication/vdiff_helper_test.go index fd223d78082..fcc112b670b 100644 --- a/go/test/endtoend/vreplication/vdiff_helper_test.go +++ b/go/test/endtoend/vreplication/vdiff_helper_test.go @@ -45,55 +45,18 @@ var ( runVDiffsSideBySide = true ) -func vdiff(t *testing.T, keyspace, workflow, cells string, vtctlclient, vtctldclient bool, wantV2Result *expectedVDiff2Result) { - if vtctlclient { - doVtctlclientVDiff(t, keyspace, workflow, cells, wantV2Result) - } - if vtctldclient { - doVtctldclientVDiff(t, keyspace, workflow, cells, wantV2Result) - } +func vdiff(t *testing.T, keyspace, workflow, cells string, wantV2Result *expectedVDiff2Result) { + doVtctldclientVDiff(t, keyspace, workflow, cells, wantV2Result) } -// vdiffSideBySide will run the VDiff command using both vtctlclient -// and vtctldclient. -func vdiffSideBySide(t *testing.T, ksWorkflow, cells string) { +func doVDiff(t *testing.T, ksWorkflow, cells string) { arr := strings.Split(ksWorkflow, ".") keyspace := arr[0] workflowName := arr[1] - if !runVDiffsSideBySide { - doVtctlclientVDiff(t, keyspace, workflowName, cells, nil) - return - } - vdiff(t, keyspace, workflowName, cells, true, true, nil) -} - -func doVtctlclientVDiff(t *testing.T, keyspace, workflow, cells string, want *expectedVDiff2Result) { - ksWorkflow := fmt.Sprintf("%s.%s", keyspace, workflow) - t.Run(fmt.Sprintf("vtctlclient vdiff %s", ksWorkflow), func(t *testing.T) { - // update-table-stats is needed in order to test progress reports. - uuid, _ := performVDiff2Action(t, true, ksWorkflow, cells, "create", "", false, "--auto-retry", - "--update-table-stats", fmt.Sprintf("--filtered_replication_wait_time=%v", vdiffTimeout/2)) - info := waitForVDiff2ToComplete(t, true, ksWorkflow, cells, uuid, time.Time{}) - require.NotNil(t, info) - require.Equal(t, workflow, info.Workflow) - require.Equal(t, keyspace, info.Keyspace) - if want != nil { - require.Equal(t, want.state, info.State) - require.Equal(t, strings.Join(want.shards, ","), info.Shards) - require.Equal(t, want.hasMismatch, info.HasMismatch) - } else { - require.Equal(t, "completed", info.State, "vdiff results: %+v", info) - require.False(t, info.HasMismatch, "vdiff results: %+v", info) - require.NotZero(t, info.RowsCompared) - } - if strings.Contains(t.Name(), "AcrossDBVersions") { - log.Errorf("VDiff resume cannot be guaranteed between major MySQL versions due to implied collation differences, skipping resume test...") - return - } - }) + doVtctldclientVDiff(t, keyspace, workflowName, cells, nil) } -func waitForVDiff2ToComplete(t *testing.T, useVtctlclient bool, ksWorkflow, cells, uuid string, completedAtMin time.Time) *vdiffInfo { +func waitForVDiff2ToComplete(t *testing.T, ksWorkflow, cells, uuid string, completedAtMin time.Time) *vdiffInfo { var info *vdiffInfo var jsonStr string first := true @@ -102,7 +65,7 @@ func waitForVDiff2ToComplete(t *testing.T, useVtctlclient bool, ksWorkflow, cell go func() { for { time.Sleep(vdiffStatusCheckInterval) - _, jsonStr = performVDiff2Action(t, useVtctlclient, ksWorkflow, cells, "show", uuid, false) + _, jsonStr = performVDiff2Action(t, ksWorkflow, cells, "show", uuid, false) info = getVDiffInfo(jsonStr) require.NotNil(t, info) if info.State == "completed" { @@ -169,8 +132,8 @@ func doVtctldclientVDiff(t *testing.T, keyspace, workflow, cells string, want *e if len(extraFlags) > 0 { flags = append(flags, extraFlags...) } - uuid, _ := performVDiff2Action(t, false, ksWorkflow, cells, "create", "", false, flags...) - info := waitForVDiff2ToComplete(t, false, ksWorkflow, cells, uuid, time.Time{}) + uuid, _ := performVDiff2Action(t, ksWorkflow, cells, "create", "", false, flags...) + info := waitForVDiff2ToComplete(t, ksWorkflow, cells, uuid, time.Time{}) require.NotNil(t, info) require.Equal(t, workflow, info.Workflow) require.Equal(t, keyspace, info.Keyspace) @@ -191,56 +154,34 @@ func doVtctldclientVDiff(t *testing.T, keyspace, workflow, cells string, want *e }) } -func performVDiff2Action(t *testing.T, useVtctlclient bool, ksWorkflow, cells, action, actionArg string, expectError bool, extraFlags ...string) (uuid string, output string) { +func performVDiff2Action(t *testing.T, ksWorkflow, cells, action, actionArg string, expectError bool, extraFlags ...string) (uuid string, output string) { var err error targetKeyspace, workflowName, ok := strings.Cut(ksWorkflow, ".") require.True(t, ok, "invalid keyspace.workflow value: %s", ksWorkflow) waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) - if useVtctlclient { + args := []string{"VDiff", "--target-keyspace", targetKeyspace, "--workflow", workflowName, "--format=json", action} + if strings.ToLower(action) == string(vdiff2.CreateAction) { // This will always result in us using a PRIMARY tablet, which is all // we start in many e2e tests, but it avoids the tablet picker logic // where when you ONLY specify the PRIMARY type it then picks the // shard's primary and ignores any cell settings. - args := []string{"VDiff", "--", "--tablet_types=in_order:primary,replica", "--source_cell=" + cells, "--format=json"} - if len(extraFlags) > 0 { - args = append(args, extraFlags...) - } - args = append(args, ksWorkflow, action, actionArg) - output, err = execVDiffWithRetry(t, expectError, false, args) - log.Infof("vdiff output: %+v (err: %+v)", output, err) - if !expectError { - require.Nil(t, err) - uuid = gjson.Get(output, "UUID").String() - if action != "delete" && !(action == "show" && actionArg == "all") { // A UUID is not required - require.NoError(t, err) - require.NotEmpty(t, uuid) - } - } - } else { - args := []string{"VDiff", "--target-keyspace", targetKeyspace, "--workflow", workflowName, "--format=json", action} - if strings.ToLower(action) == string(vdiff2.CreateAction) { - // This will always result in us using a PRIMARY tablet, which is all - // we start in many e2e tests, but it avoids the tablet picker logic - // where when you ONLY specify the PRIMARY type it then picks the - // shard's primary and ignores any cell settings. - args = append(args, "--tablet-types=primary,replica", "--tablet-types-in-preference-order", "--source-cells="+cells) - } - if len(extraFlags) > 0 { - args = append(args, extraFlags...) - } - if actionArg != "" { - args = append(args, actionArg) - } + args = append(args, "--tablet-types=primary,replica", "--tablet-types-in-preference-order", "--source-cells="+cells) + } + if len(extraFlags) > 0 { + args = append(args, extraFlags...) + } + if actionArg != "" { + args = append(args, actionArg) + } - output, err = execVDiffWithRetry(t, expectError, true, args) - log.Infof("vdiff output: %+v (err: %+v)", output, err) - if !expectError { - require.NoError(t, err) - ouuid := gjson.Get(output, "UUID").String() - if action == "create" || (action == "show" && actionArg != "all") { // A UUID is returned - require.NotEmpty(t, ouuid) - uuid = ouuid - } + output, err = execVDiffWithRetry(t, expectError, args) + log.Infof("vdiff output: %+v (err: %+v)", output, err) + if !expectError { + require.NoError(t, err) + ouuid := gjson.Get(output, "UUID").String() + if action == "create" || (action == "show" && actionArg != "all") { // A UUID is returned + require.NotEmpty(t, ouuid) + uuid = ouuid } } @@ -264,7 +205,7 @@ type vdiffResult struct { } // execVDiffWithRetry will ignore transient errors that can occur during workflow state changes. -func execVDiffWithRetry(t *testing.T, expectError bool, useVtctldClient bool, args []string) (string, error) { +func execVDiffWithRetry(t *testing.T, expectError bool, args []string) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), vdiffRetryTimeout) defer cancel() vdiffResultCh := make(chan vdiffResult) @@ -282,11 +223,7 @@ func execVDiffWithRetry(t *testing.T, expectError bool, useVtctldClient bool, ar time.Sleep(vdiffRetryInterval) } retry = false - if useVtctldClient { - output, err = vc.VtctldClient.ExecuteCommandWithOutput(args...) - } else { - output, err = vc.VtctlClient.ExecuteCommandWithOutput(args...) - } + output, err = vc.VtctldClient.ExecuteCommandWithOutput(args...) if err != nil { if expectError { result := vdiffResult{output: output, err: err} diff --git a/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go b/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go index a4c25941801..d668701100e 100644 --- a/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go +++ b/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go @@ -102,7 +102,7 @@ func TestMultipleConcurrentVDiffs(t *testing.T) { doVdiff := func(workflowName, table string) { defer wg.Done() - vdiff(t, targetKeyspace, workflowName, cellName, true, false, nil) + vdiff(t, targetKeyspace, workflowName, cellName, nil) } go doVdiff("wf1", "customer") go doVdiff("wf2", "customer2") diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go index d3193298a0c..617e5f79f6a 100644 --- a/go/test/endtoend/vreplication/vreplication_test.go +++ b/go/test/endtoend/vreplication/vreplication_test.go @@ -286,7 +286,7 @@ func TestVreplicationCopyThrottling(t *testing.T) { moveTablesActionWithTabletTypes(t, "Create", defaultCell.Name, workflow, sourceKs, targetKs, table, "primary", true) // Wait for the copy phase to start waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKs, workflow), binlogdatapb.VReplicationWorkflowState_Copying.String()) - // The initial copy phase should be blocking on the history list + // The initial copy phase should be blocking on the history list. confirmWorkflowHasCopiedNoData(t, targetKs, workflow) releaseInnoDBRowHistory(t, trxConn) trxConn.Close() @@ -323,8 +323,10 @@ func testVreplicationWorkflows(t *testing.T, limited bool, binlogRowImage string defer func() { defaultReplicas = 1 }() if binlogRowImage != "" { - require.NoError(t, utils.SetBinlogRowImageMode("noblob", vc.ClusterConfig.tmpDir)) - defer utils.SetBinlogRowImageMode("", vc.ClusterConfig.tmpDir) + // Run the e2e test with binlog_row_image=NOBLOB and + // binlog_row_value_options=PARTIAL_JSON. + require.NoError(t, utils.SetBinlogRowImageOptions("noblob", true, vc.ClusterConfig.tmpDir)) + defer utils.SetBinlogRowImageOptions("", false, vc.ClusterConfig.tmpDir) } defaultCell := vc.Cells[defaultCellName] @@ -334,7 +336,7 @@ func testVreplicationWorkflows(t *testing.T, limited bool, binlogRowImage string defer vtgateConn.Close() verifyClusterHealth(t, vc) insertInitialData(t) - materializeRollup(t, true) + materializeRollup(t) shardCustomer(t, true, []*Cell{defaultCell}, defaultCellName, false) @@ -349,11 +351,11 @@ func testVreplicationWorkflows(t *testing.T, limited bool, binlogRowImage string return } - materializeProduct(t, true) + materializeProduct(t) - materializeMerchantOrders(t, true) - materializeSales(t, true) - materializeMerchantSales(t, true) + materializeMerchantOrders(t) + materializeSales(t) + materializeMerchantSales(t) reshardMerchant2to3SplitMerge(t) reshardMerchant3to1Merge(t) @@ -415,6 +417,14 @@ func testVreplicationWorkflows(t *testing.T, limited bool, binlogRowImage string vdx = gjson.Get(customerVSchema, fmt.Sprintf("vindexes.%s", vindexName)) require.NotNil(t, vdx, "lookup vindex %s not found", vindexName) require.NotEqual(t, "true", vdx.Get("params.write_only").String(), "did not expect write_only parameter to be true") + + err = vc.VtctldClient.ExecuteCommand("LookupVindex", "--name", vindexName, "--table-keyspace=product", "internalize", "--keyspace=customer") + require.NoError(t, err, "error executing LookupVindex internalize: %v", err) + customerVSchema, err = vc.VtctldClient.ExecuteCommandWithOutput("GetVSchema", "customer") + require.NoError(t, err, "error executing GetVSchema: %v", err) + vdx = gjson.Get(customerVSchema, fmt.Sprintf("vindexes.%s", vindexName)) + require.NotNil(t, vdx, "lookup vindex %s not found", vindexName) + require.Equal(t, "true", vdx.Get("params.write_only").String(), "expected write_only parameter to be true") }) } @@ -497,13 +507,13 @@ func TestVStreamFlushBinlog(t *testing.T) { // Now we should rotate the binary logs ONE time on the source, even // though we're opening up multiple result streams (1 per table). runVDiffsSideBySide = false - vdiff(t, targetKs, workflow, defaultCellName, true, false, nil) + vdiff(t, targetKs, workflow, defaultCellName, nil) flushCount = int64(sourceTab.GetVars()["VStreamerFlushedBinlogs"].(float64)) require.Equal(t, flushCount, int64(1), "VStreamerFlushedBinlogs should now be 1") // Now if we do another vdiff, we should NOT rotate the binlogs again // as we haven't been generating a lot of new binlog events. - vdiff(t, targetKs, workflow, defaultCellName, true, false, nil) + vdiff(t, targetKs, workflow, defaultCellName, nil) flushCount = int64(sourceTab.GetVars()["VStreamerFlushedBinlogs"].(float64)) require.Equal(t, flushCount, int64(1), "VStreamerFlushedBinlogs should still be 1") } @@ -600,8 +610,10 @@ func TestCellAliasVreplicationWorkflow(t *testing.T) { keyspace := "product" shard := "0" - require.NoError(t, utils.SetBinlogRowImageMode("noblob", vc.ClusterConfig.tmpDir)) - defer utils.SetBinlogRowImageMode("", vc.ClusterConfig.tmpDir) + // Run the e2e test with binlog_row_image=NOBLOB and + // binlog_row_value_options=PARTIAL_JSON. + require.NoError(t, utils.SetBinlogRowImageOptions("noblob", true, vc.ClusterConfig.tmpDir)) + defer utils.SetBinlogRowImageOptions("", false, vc.ClusterConfig.tmpDir) cell1 := vc.Cells["zone1"] cell2 := vc.Cells["zone2"] @@ -619,7 +631,7 @@ func TestCellAliasVreplicationWorkflow(t *testing.T) { testVStreamFrom(t, vtgate, keyspace, 2) }) shardCustomer(t, true, []*Cell{cell1, cell2}, "alias", false) - isTableInDenyList(t, vc, "product:0", "customer") + isTableInDenyList(t, vc, "product/0", "customer") // we tag along this test so as not to create the overhead of creating another cluster testVStreamCellFlag(t) } @@ -721,8 +733,18 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl // Confirm that the 0 scale decimal field, dec80, is replicated correctly execVtgateQuery(t, vtgateConn, sourceKs, "update customer set dec80 = 0") execVtgateQuery(t, vtgateConn, sourceKs, "update customer set blb = \"new blob data\" where cid=3") - execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j1 = null, j2 = 'null', j3 = '\"null\"'") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j1 = null, j2 = 'null', j3 = '\"null\"' where id = 5") execVtgateQuery(t, vtgateConn, sourceKs, "insert into json_tbl(id, j1, j2, j3) values (7, null, 'null', '\"null\"')") + // Test binlog-row-value-options=PARTIAL_JSON + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_SET(j3, '$.role', 'manager')") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_SET(j3, '$.color', 'red')") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_SET(j3, '$.day', 'wednesday')") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_INSERT(JSON_REPLACE(j3, '$.day', 'friday'), '$.favorite_color', 'black')") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_SET(JSON_REMOVE(JSON_REPLACE(j3, '$.day', 'monday'), '$.favorite_color'), '$.hobby', 'skiing') where id = 3") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_SET(JSON_REMOVE(JSON_REPLACE(j3, '$.day', 'tuesday'), '$.favorite_color'), '$.hobby', 'skiing') where id = 4") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_SET(JSON_SET(j3, '$.salary', 110), '$.role', 'IC') where id = 4") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j3 = JSON_SET(j3, '$.misc', '{\"address\":\"1012 S Park St\", \"town\":\"Hastings\", \"state\":\"MI\"}') where id = 1") + execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set id=id+1000, j3=JSON_SET(j3, '$.day', 'friday')") waitForNoWorkflowLag(t, vc, targetKs, workflow) dec80Replicated := false for _, tablet := range []*cluster.VttabletProcess{customerTab1, customerTab2} { @@ -788,7 +810,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl execVtgateQuery(t, vtgateConn, "product", fmt.Sprintf("update `%s` set name='xyz'", tbl)) } } - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") cellNames := getCellNames(cells) switchReadsDryRun(t, workflowType, cellNames, ksWorkflow, dryRunResultsReadCustomerShard) switchReads(t, workflowType, cellNames, ksWorkflow, false) @@ -820,7 +842,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl catchup(t, productTab, workflow, "MoveTables") - vdiffSideBySide(t, "product.p2c_reverse", "") + doVDiff(t, "product.p2c_reverse", "") if withOpenTx { execVtgateQuery(t, vtgateConn, "", deleteOpenTxQuery) } @@ -864,13 +886,13 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl switchWrites(t, workflowType, ksWorkflow, false) var exists bool - exists, err = isTableInDenyList(t, vc, "product:0", "customer") + exists, err = isTableInDenyList(t, vc, "product/0", "customer") require.NoError(t, err, "Error getting denylist for customer:0") require.True(t, exists) moveTablesAction(t, "Complete", cellNames, workflow, sourceKs, targetKs, tables) - exists, err = isTableInDenyList(t, vc, "product:0", "customer") + exists, err = isTableInDenyList(t, vc, "product/0", "customer") require.NoError(t, err, "Error getting denylist for customer:0") require.False(t, exists) @@ -1055,7 +1077,7 @@ func reshard(t *testing.T, ksName string, tableName string, workflow string, sou } } restartWorkflow(t, ksWorkflow) - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") if dryRunResultSwitchReads != nil { reshardAction(t, "SwitchTraffic", workflow, ksName, "", "", callNames, "rdonly,replica", "--dry-run") } @@ -1094,7 +1116,7 @@ func shardOrders(t *testing.T) { workflowType := "MoveTables" catchup(t, customerTab1, workflow, workflowType) catchup(t, customerTab2, workflow, workflowType) - vdiffSideBySide(t, ksWorkflow, "") + doVDiff(t, ksWorkflow, "") switchReads(t, workflowType, strings.Join(vc.CellNames, ","), ksWorkflow, false) switchWrites(t, workflowType, ksWorkflow, false) moveTablesAction(t, "Complete", cell, workflow, sourceKs, targetKs, tables) @@ -1105,17 +1127,10 @@ func shardOrders(t *testing.T) { } func checkThatVDiffFails(t *testing.T, keyspace, workflow string) { - ksWorkflow := fmt.Sprintf("%s.%s", keyspace, workflow) - t.Run("check that vdiffSideBySide won't run", func(t2 *testing.T) { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("VDiff", "--", "--v1", ksWorkflow) - require.Error(t, err) - require.Contains(t, output, "invalid VDiff run") - }) - t.Run("check that vdiff2 won't run", func(t2 *testing.T) { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("VDiff", "--", ksWorkflow) + t.Run("check that vdiff won't run", func(t2 *testing.T) { + output, err := vc.VtctldClient.ExecuteCommandWithOutput("VDiff", "--workflow", workflow, "--target-keyspace", keyspace, "create") require.Error(t, err) require.Contains(t, output, "invalid VDiff run") - }) } @@ -1141,7 +1156,7 @@ func shardMerchant(t *testing.T) { catchup(t, merchantTab1, workflow, workflowType) catchup(t, merchantTab2, workflow, workflowType) - vdiffSideBySide(t, fmt.Sprintf("%s.%s", merchantKeyspace, workflow), "") + doVDiff(t, fmt.Sprintf("%s.%s", merchantKeyspace, workflow), "") switchReads(t, workflowType, strings.Join(vc.CellNames, ","), ksWorkflow, false) switchWrites(t, workflowType, ksWorkflow, false) printRoutingRules(t, vc, "After merchant movetables") @@ -1160,34 +1175,25 @@ func shardMerchant(t *testing.T) { }) } -func materialize(t *testing.T, spec string, useVtctldClient bool) { - if useVtctldClient { - t.Run("vtctldclient materialize", func(t *testing.T) { - // Split out the parameters from the JSON spec for - // use in the vtctldclient command flags. - // This allows us to test both clients with the same - // input. - sj := gjson.Parse(spec) - workflow := sj.Get("workflow").String() - require.NotEmpty(t, workflow, "workflow not found in spec: %s", spec) - sourceKeyspace := sj.Get("source_keyspace").String() - require.NotEmpty(t, sourceKeyspace, "source_keyspace not found in spec: %s", spec) - targetKeyspace := sj.Get("target_keyspace").String() - require.NotEmpty(t, targetKeyspace, "target_keyspace not found in spec: %s", spec) - tableSettings := sj.Get("table_settings").String() - require.NotEmpty(t, tableSettings, "table_settings not found in spec: %s", spec) - stopAfterCopy := sj.Get("stop-after-copy").Bool() // Optional - err := vc.VtctldClient.ExecuteCommand("materialize", "--workflow", workflow, "--target-keyspace", targetKeyspace, - "create", "--source-keyspace", sourceKeyspace, "--table-settings", tableSettings, - fmt.Sprintf("--stop-after-copy=%t", stopAfterCopy)) - require.NoError(t, err, "Materialize") - }) - } else { - t.Run("materialize", func(t *testing.T) { - err := vc.VtctlClient.ExecuteCommand("Materialize", spec) - require.NoError(t, err, "Materialize") - }) - } +func materialize(t *testing.T, spec string) { + t.Run("materialize", func(t *testing.T) { + // Split out the parameters from the JSON spec for + // use in the vtctldclient command flags. + sj := gjson.Parse(spec) + workflow := sj.Get("workflow").String() + require.NotEmpty(t, workflow, "workflow not found in spec: %s", spec) + sourceKeyspace := sj.Get("source_keyspace").String() + require.NotEmpty(t, sourceKeyspace, "source_keyspace not found in spec: %s", spec) + targetKeyspace := sj.Get("target_keyspace").String() + require.NotEmpty(t, targetKeyspace, "target_keyspace not found in spec: %s", spec) + tableSettings := sj.Get("table_settings").String() + require.NotEmpty(t, tableSettings, "table_settings not found in spec: %s", spec) + stopAfterCopy := sj.Get("stop-after-copy").Bool() // Optional + err := vc.VtctldClient.ExecuteCommand("materialize", "--workflow", workflow, "--target-keyspace", targetKeyspace, + "create", "--source-keyspace", sourceKeyspace, "--table-settings", tableSettings, + fmt.Sprintf("--stop-after-copy=%t", stopAfterCopy)) + require.NoError(t, err, "Materialize") + }) } func testMaterializeWithNonExistentTable(t *testing.T) { @@ -1202,14 +1208,14 @@ func testMaterializeWithNonExistentTable(t *testing.T) { }) } -func materializeProduct(t *testing.T, useVtctldClient bool) { +func materializeProduct(t *testing.T) { t.Run("materializeProduct", func(t *testing.T) { // Materializing from "product" keyspace to "customer" keyspace. workflow := "cproduct" keyspace := "customer" defaultCell := vc.Cells[vc.CellNames[0]] applyVSchema(t, materializeProductVSchema, keyspace) - materialize(t, materializeProductSpec, useVtctldClient) + materialize(t, materializeProductSpec) customerTablets := vc.getVttabletsInKeyspace(t, defaultCell, keyspace, "primary") for _, tab := range customerTablets { catchup(t, tab, workflow, "Materialize") @@ -1289,7 +1295,7 @@ func materializeProduct(t *testing.T, useVtctldClient bool) { }) } -func materializeRollup(t *testing.T, useVtctldClient bool) { +func materializeRollup(t *testing.T) { t.Run("materializeRollup", func(t *testing.T) { vtgateConn := getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) defer vtgateConn.Close() @@ -1298,7 +1304,7 @@ func materializeRollup(t *testing.T, useVtctldClient bool) { applyVSchema(t, materializeSalesVSchema, keyspace) defaultCell := vc.Cells[vc.CellNames[0]] productTab := vc.Cells[defaultCell.Name].Keyspaces["product"].Shards["0"].Tablets["zone1-100"].Vttablet - materialize(t, materializeRollupSpec, useVtctldClient) + materialize(t, materializeRollupSpec) catchup(t, productTab, workflow, "Materialize") waitForRowCount(t, vtgateConn, "product", "rollup", 1) waitForQueryResult(t, vtgateConn, "product:0", "select rollupname, kount from rollup", @@ -1306,13 +1312,13 @@ func materializeRollup(t *testing.T, useVtctldClient bool) { }) } -func materializeSales(t *testing.T, useVtctldClient bool) { +func materializeSales(t *testing.T) { t.Run("materializeSales", func(t *testing.T) { vtgateConn := getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) defer vtgateConn.Close() keyspace := "product" applyVSchema(t, materializeSalesVSchema, keyspace) - materialize(t, materializeSalesSpec, useVtctldClient) + materialize(t, materializeSalesSpec) defaultCell := vc.Cells[vc.CellNames[0]] productTab := vc.Cells[defaultCell.Name].Keyspaces["product"].Shards["0"].Tablets["zone1-100"].Vttablet catchup(t, productTab, "sales", "Materialize") @@ -1322,12 +1328,12 @@ func materializeSales(t *testing.T, useVtctldClient bool) { }) } -func materializeMerchantSales(t *testing.T, useVtctldClient bool) { +func materializeMerchantSales(t *testing.T) { t.Run("materializeMerchantSales", func(t *testing.T) { vtgateConn := getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) defer vtgateConn.Close() workflow := "msales" - materialize(t, materializeMerchantSalesSpec, useVtctldClient) + materialize(t, materializeMerchantSalesSpec) defaultCell := vc.Cells[vc.CellNames[0]] merchantTablets := vc.getVttabletsInKeyspace(t, defaultCell, merchantKeyspace, "primary") for _, tab := range merchantTablets { @@ -1339,14 +1345,14 @@ func materializeMerchantSales(t *testing.T, useVtctldClient bool) { }) } -func materializeMerchantOrders(t *testing.T, useVtctldClient bool) { +func materializeMerchantOrders(t *testing.T) { t.Run("materializeMerchantOrders", func(t *testing.T) { vtgateConn := getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) defer vtgateConn.Close() workflow := "morders" keyspace := merchantKeyspace applyVSchema(t, merchantOrdersVSchema, keyspace) - materialize(t, materializeMerchantOrdersSpec, useVtctldClient) + materialize(t, materializeMerchantOrdersSpec) defaultCell := vc.Cells[vc.CellNames[0]] merchantTablets := vc.getVttabletsInKeyspace(t, defaultCell, merchantKeyspace, "primary") for _, tab := range merchantTablets { @@ -1739,12 +1745,12 @@ func waitForInnoDBHistoryLength(t *testing.T, tablet *cluster.VttabletProcess, e require.Equal(t, 1, len(res.Rows)) historyLen, err = res.Rows[0][0].ToInt64() require.NoError(t, err) - if historyLen > expectedLength { + if historyLen >= expectedLength { return } select { case <-timer.C: - t.Fatalf("Did not reach the expected InnoDB history length of %d before the timeout of %s; last seen value: %d", expectedLength, defaultTimeout, historyLen) + require.FailNow(t, "Did not reach the minimum expected InnoDB history length of %d before the timeout of %s; last seen value: %d", expectedLength, defaultTimeout, historyLen) default: time.Sleep(defaultTick) } diff --git a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go index 4ee977c4d74..6cce3fe9fa6 100644 --- a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go +++ b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go @@ -25,6 +25,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" "golang.org/x/exp/maps" "google.golang.org/protobuf/encoding/protojson" @@ -57,7 +58,7 @@ func TestVtctldclientCLI(t *testing.T) { vc = setupMinimalCluster(t) vttablet.InitVReplicationConfigDefaults() - err = vc.Vtctl.AddCellInfo("zone2") + err = vc.VtctldClient.AddCellInfo("zone2") require.NoError(t, err) zone2, err := vc.AddCell(t, "zone2") require.NoError(t, err) @@ -180,7 +181,7 @@ func testMoveTablesFlags2(t *testing.T, mt *iMoveTables, sourceKeyspace, targetK for _, tab := range targetTabs { alias := fmt.Sprintf("zone1-%d", tab.TabletUID) query := "update _vt.vreplication set source := replace(source, 'stop_after_copy:true', 'stop_after_copy:false') where db_name = 'vt_customer' and workflow = 'wf1'" - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ExecuteFetchAsDba", alias, query) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ExecuteFetchAsDBA", alias, query) require.NoError(t, err, output) } confirmNoRoutingRules(t) @@ -263,7 +264,7 @@ func testMoveTablesFlags2(t *testing.T, mt *iMoveTables, sourceKeyspace, targetK confirmStates(t, &wf, wrangler.WorkflowStateReadsSwitched, wrangler.WorkflowStateNotSwitched) // Confirm that everything is still in sync after our switch fest. - vdiff(t, targetKeyspace, workflowName, "zone1", false, true, nil) + vdiff(t, targetKeyspace, workflowName, "zone1", nil) (*mt).SwitchReadsAndWrites() validateReadsRouteToTarget(t, "replica") @@ -282,7 +283,7 @@ func testMoveTablesFlags2(t *testing.T, mt *iMoveTables, sourceKeyspace, targetK func testMoveTablesFlags3(t *testing.T, sourceKeyspace, targetKeyspace string, targetTabs map[string]*cluster.VttabletProcess) { for _, tab := range targetTabs { alias := fmt.Sprintf("zone1-%d", tab.TabletUID) - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ExecuteFetchAsDba", alias, "drop table customer") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ExecuteFetchAsDBA", alias, "drop table customer") require.NoError(t, err, output) } createFlags := []string{} @@ -492,7 +493,7 @@ func splitShard(t *testing.T, keyspace, workflowName, sourceShards, targetShards for _, tab := range targetTabs { alias := fmt.Sprintf("zone1-%d", tab.TabletUID) query := "update _vt.vreplication set source := replace(source, 'stop_after_copy:true', 'stop_after_copy:false') where db_name = 'vt_customer' and workflow = '" + workflowName + "'" - output, err := vc.VtctlClient.ExecuteCommandWithOutput("ExecuteFetchAsDba", alias, query) + output, err := vc.VtctldClient.ExecuteCommandWithOutput("ExecuteFetchAsDBA", alias, query) require.NoError(t, err, output) } rs.Start() @@ -501,10 +502,32 @@ func splitShard(t *testing.T, keyspace, workflowName, sourceShards, targetShards waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Stopped.String()) rs.Start() waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", keyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) + + t.Run("Test --shards in workflow start/stop", func(t *testing.T) { + // This subtest expects workflow to be running at the start and restarts it at the end. + type tCase struct { + shards string + action string + expected int + } + testCases := []tCase{ + {"-40", "stop", 1}, + {"40-80", "stop", 1}, + {"-40,40-80", "start", 2}, + } + for _, tc := range testCases { + output, err := vc.VtctldClient.ExecuteCommandWithOutput("workflow", "--keyspace", keyspace, tc.action, "--workflow", workflowName, "--shards", tc.shards) + require.NoError(t, err, "failed to %s workflow: %v", tc.action, err) + cnt := gjson.Get(output, "details.#").Int() + require.EqualValuesf(t, tc.expected, cnt, "expected %d shards, got %d for action %s, shards %s", tc.expected, cnt, tc.action, tc.shards) + } + }) + waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", keyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) + for _, targetTab := range targetTabs { catchup(t, targetTab, workflowName, "Reshard") } - vdiff(t, keyspace, workflowName, "zone1", false, true, nil) + vdiff(t, keyspace, workflowName, "zone1", nil) shardReadsRouteToSource := func() { require.True(t, getShardRoute(t, keyspace, "-80", "replica")) @@ -524,14 +547,14 @@ func splitShard(t *testing.T, keyspace, workflowName, sourceShards, targetShards rs.SwitchReadsAndWrites() waitForLowLag(t, keyspace, workflowName+"_reverse") - vdiff(t, keyspace, workflowName+"_reverse", "zone1", true, false, nil) + vdiff(t, keyspace, workflowName+"_reverse", "zone1", nil) shardReadsRouteToTarget() shardWritesRouteToTarget() confirmStates(t, &wf, wrangler.WorkflowStateNotSwitched, wrangler.WorkflowStateAllSwitched) rs.ReverseReadsAndWrites() waitForLowLag(t, keyspace, workflowName) - vdiff(t, keyspace, workflowName, "zone1", false, true, nil) + vdiff(t, keyspace, workflowName, "zone1", nil) shardReadsRouteToSource() shardWritesRouteToSource() confirmStates(t, &wf, wrangler.WorkflowStateAllSwitched, wrangler.WorkflowStateNotSwitched) @@ -587,7 +610,7 @@ func splitShard(t *testing.T, keyspace, workflowName, sourceShards, targetShards confirmStates(t, &wf, wrangler.WorkflowStateReadsSwitched, wrangler.WorkflowStateNotSwitched) // Confirm that everything is still in sync after our switch fest. - vdiff(t, keyspace, workflowName, "zone1", false, true, nil) + vdiff(t, keyspace, workflowName, "zone1", nil) rs.SwitchReadsAndWrites() shardReadsRouteToTarget() diff --git a/go/test/endtoend/vreplication/vschema_load_test.go b/go/test/endtoend/vreplication/vschema_load_test.go index 6ca8dcfe472..e14d3be8720 100644 --- a/go/test/endtoend/vreplication/vschema_load_test.go +++ b/go/test/endtoend/vreplication/vschema_load_test.go @@ -120,7 +120,7 @@ func TestVSchemaChangesUnderLoad(t *testing.T) { defer timer.Stop() log.Infof("Started ApplyVSchema") for { - if err := vc.VtctlClient.ExecuteCommand("ApplyVSchema", "--", "--vschema={}", "product"); err != nil { + if err := vc.VtctldClient.ExecuteCommand("ApplyVSchema", "--vschema={}", "product"); err != nil { log.Errorf("ApplyVSchema command failed with %+v\n", err) return } @@ -140,8 +140,8 @@ func TestVSchemaChangesUnderLoad(t *testing.T) { }() <-ch // wait for enough ApplyVSchema calls before doing a PRS - if err := vc.VtctlClient.ExecuteCommand("PlannedReparentShard", "--", "--keyspace_shard", "product/0", - "--new_primary", "zone1-101", "--wait_replicas_timeout", defaultTimeout.String()); err != nil { + if err := vc.VtctldClient.ExecuteCommand("PlannedReparentShard", "product/0", + "--new-primary", "zone1-101", "--wait-replicas-timeout", defaultTimeout.String()); err != nil { require.NoError(t, err, "PlannedReparentShard command failed") } } diff --git a/go/test/endtoend/vreplication/vstream_test.go b/go/test/endtoend/vreplication/vstream_test.go index 3f79a35b569..7009bade562 100644 --- a/go/test/endtoend/vreplication/vstream_test.go +++ b/go/test/endtoend/vreplication/vstream_test.go @@ -28,7 +28,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/log" - _ "vitess.io/vitess/go/vt/vtctl/grpcvtctlclient" _ "vitess.io/vitess/go/vt/vtgate/grpcvtgateconn" "vitess.io/vitess/go/vt/vtgate/vtgateconn" @@ -140,7 +139,7 @@ func testVStreamWithFailover(t *testing.T, failover bool) { case 1: if failover { insertMu.Lock() - output, err := vc.VtctlClient.ExecuteCommandWithOutput("PlannedReparentShard", "--", "--keyspace_shard=product/0", "--new_primary=zone1-101") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("PlannedReparentShard", "product/0", "--new-primary=zone1-101") insertMu.Unlock() log.Infof("output of first PRS is %s", output) require.NoError(t, err) @@ -148,7 +147,7 @@ func testVStreamWithFailover(t *testing.T, failover bool) { case 2: if failover { insertMu.Lock() - output, err := vc.VtctlClient.ExecuteCommandWithOutput("PlannedReparentShard", "--", "--keyspace_shard=product/0", "--new_primary=zone1-100") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("PlannedReparentShard", "product/0", "--new-primary=zone1-100") insertMu.Unlock() log.Infof("output of second PRS is %s", output) require.NoError(t, err) @@ -655,6 +654,8 @@ func TestMultiVStreamsKeyspaceReshard(t *testing.T) { // Confirm that we have shard GTIDs for the global shard and the old/original shards. require.Len(t, newVGTID.GetShardGtids(), 3) + waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", ks, wf), binlogdatapb.VReplicationWorkflowState_Running.String()) + // Switch the traffic to the new shards. reshardAction(t, "SwitchTraffic", wf, ks, oldShards, newShards, defaultCellName, tabletType) diff --git a/go/test/endtoend/vreplication/wrappers_test.go b/go/test/endtoend/vreplication/wrappers_test.go index d1fff1af1c6..2ca1b3bb724 100644 --- a/go/test/endtoend/vreplication/wrappers_test.go +++ b/go/test/endtoend/vreplication/wrappers_test.go @@ -24,7 +24,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/log" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) type iWorkflow interface { @@ -50,17 +49,14 @@ type workflowFlavor int const ( workflowFlavorRandom workflowFlavor = iota - workflowFlavorVtctl workflowFlavorVtctld ) var workflowFlavors = []workflowFlavor{ - workflowFlavorVtctl, workflowFlavorVtctld, } var workflowFlavorNames = map[workflowFlavor]string{ - workflowFlavorVtctl: "vtctl", workflowFlavorVtctld: "vtctld", } @@ -100,8 +96,6 @@ func newMoveTables(vc *VitessCluster, mt *moveTablesWorkflow, flavor workflowFla flavor = workflowFlavors[rand.IntN(len(workflowFlavors))] } switch flavor { - case workflowFlavorVtctl: - mt2 = newVtctlMoveTables(mt) case workflowFlavorVtctld: mt2 = newVtctldMoveTables(mt) default: @@ -111,102 +105,6 @@ func newMoveTables(vc *VitessCluster, mt *moveTablesWorkflow, flavor workflowFla return mt2 } -type VtctlMoveTables struct { - *moveTablesWorkflow -} - -func (vmt *VtctlMoveTables) Flavor() string { - return "vtctl" -} - -func newVtctlMoveTables(mt *moveTablesWorkflow) *VtctlMoveTables { - return &VtctlMoveTables{mt} -} - -func (vmt *VtctlMoveTables) Create() { - currentWorkflowType = binlogdatapb.VReplicationWorkflowType_MoveTables - vmt.exec(workflowActionCreate) -} - -func (vmt *VtctlMoveTables) MirrorTraffic() { - // TODO implement me - panic("implement me") -} - -func (vmt *VtctlMoveTables) SwitchReadsAndWrites() { - err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions) - require.NoError(vmt.vc.t, err) -} - -func (vmt *VtctlMoveTables) ReverseReadsAndWrites() { - err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionReverseTraffic, "", "", "", defaultWorkflowExecOptions) - require.NoError(vmt.vc.t, err) -} - -func (vmt *VtctlMoveTables) Show() { - // TODO implement me - panic("implement me") -} - -func (vmt *VtctlMoveTables) Status() { - currentWorkflowType = binlogdatapb.VReplicationWorkflowType_MoveTables - vmt.exec("Status") -} - -func (vmt *VtctlMoveTables) exec(action string) { - options := &workflowExecOptions{ - deferSecondaryKeys: false, - atomicCopy: vmt.atomicCopy, - } - err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, action, vmt.tabletTypes, vmt.sourceShards, "", options) - require.NoError(vmt.vc.t, err) -} -func (vmt *VtctlMoveTables) SwitchReads() { - err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionSwitchTraffic, "replica,rdonly", "", "", defaultWorkflowExecOptions) - require.NoError(vmt.vc.t, err) -} - -func (vmt *VtctlMoveTables) SwitchWrites() { - err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionSwitchTraffic, "primary", "", "", defaultWorkflowExecOptions) - require.NoError(vmt.vc.t, err) -} -func (vmt *VtctlMoveTables) ReverseReads() { - err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionReverseTraffic, "replica,rdonly", "", "", defaultWorkflowExecOptions) - require.NoError(vmt.vc.t, err) -} - -func (vmt *VtctlMoveTables) ReverseWrites() { - err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionReverseTraffic, "primary", "", "", defaultWorkflowExecOptions) - require.NoError(vmt.vc.t, err) -} - -func (vmt *VtctlMoveTables) Cancel() { - vmt.exec(workflowActionCancel) -} - -func (vmt *VtctlMoveTables) Complete() { - vmt.exec(workflowActionComplete) -} - -func (vmt *VtctlMoveTables) GetLastOutput() string { - return vmt.lastOutput -} - -func (vmt *VtctlMoveTables) Start() { - panic("implement me") -} - -func (vmt *VtctlMoveTables) Stop() { - panic("implement me") -} - var _ iMoveTables = (*VtctldMoveTables)(nil) type VtctldMoveTables struct { @@ -347,8 +245,6 @@ func newReshard(vc *VitessCluster, rs *reshardWorkflow, flavor workflowFlavor) i flavor = workflowFlavors[rand.IntN(len(workflowFlavors))] } switch flavor { - case workflowFlavorVtctl: - rs2 = newVtctlReshard(rs) case workflowFlavorVtctld: rs2 = newVtctldReshard(rs) default: @@ -358,93 +254,6 @@ func newReshard(vc *VitessCluster, rs *reshardWorkflow, flavor workflowFlavor) i return rs2 } -type VtctlReshard struct { - *reshardWorkflow -} - -func (vrs *VtctlReshard) ReverseReads() { - //TODO implement me - panic("implement me") -} - -func (vrs *VtctlReshard) ReverseWrites() { - //TODO implement me - panic("implement me") -} - -func (vrs *VtctlReshard) Flavor() string { - return "vtctl" -} - -func newVtctlReshard(rs *reshardWorkflow) *VtctlReshard { - return &VtctlReshard{rs} -} - -func (vrs *VtctlReshard) Create() { - currentWorkflowType = binlogdatapb.VReplicationWorkflowType_Reshard - vrs.exec(workflowActionCreate) -} - -func (vrs *VtctlReshard) MirrorTraffic() { - // TODO implement me - panic("implement me") -} - -func (vrs *VtctlReshard) Status() { - currentWorkflowType = binlogdatapb.VReplicationWorkflowType_Reshard - vrs.exec("Status") -} - -func (vrs *VtctlReshard) SwitchReadsAndWrites() { - vrs.exec(workflowActionSwitchTraffic) -} - -func (vrs *VtctlReshard) ReverseReadsAndWrites() { - vrs.exec(workflowActionReverseTraffic) -} - -func (vrs *VtctlReshard) Show() { - // TODO implement me - panic("implement me") -} - -func (vrs *VtctlReshard) exec(action string) { - options := &workflowExecOptions{} - err := tstWorkflowExecVtctl(vrs.vc.t, "", vrs.workflowName, "", vrs.targetKeyspace, - "", action, vrs.tabletTypes, vrs.sourceShards, vrs.targetShards, options) - require.NoError(vrs.vc.t, err) -} - -func (vrs *VtctlReshard) SwitchReads() { - // TODO implement me - panic("implement me") -} - -func (vrs *VtctlReshard) SwitchWrites() { - // TODO implement me - panic("implement me") -} - -func (vrs *VtctlReshard) Cancel() { - vrs.exec(workflowActionCancel) -} - -func (vrs *VtctlReshard) Complete() { - vrs.exec(workflowActionComplete) -} - -func (vrs *VtctlReshard) GetLastOutput() string { - return vrs.lastOutput -} - -func (vrs *VtctlReshard) Start() { - panic("implement me") -} - -func (vrs *VtctlReshard) Stop() { - panic("implement me") -} - var _ iReshard = (*VtctldReshard)(nil) type VtctldReshard struct { diff --git a/go/test/endtoend/vtadmin/main_test.go b/go/test/endtoend/vtadmin/main_test.go index fd4ecbdb7fe..9233cd5b0aa 100644 --- a/go/test/endtoend/vtadmin/main_test.go +++ b/go/test/endtoend/vtadmin/main_test.go @@ -51,7 +51,6 @@ create table u_b ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -92,7 +91,6 @@ func TestMain(m *testing.M) { // TestVtadminAPIs tests the vtadmin APIs. func TestVtadminAPIs(t *testing.T) { - defer cluster.PanicHandler(t) // Test the vtadmin APIs t.Run("keyspaces api", func(t *testing.T) { diff --git a/go/test/endtoend/vtcombo/recreate/recreate_test.go b/go/test/endtoend/vtcombo/recreate/recreate_test.go index 15cb63c3d7d..496d26c8062 100644 --- a/go/test/endtoend/vtcombo/recreate/recreate_test.go +++ b/go/test/endtoend/vtcombo/recreate/recreate_test.go @@ -132,9 +132,9 @@ func getMySQLConnectionCount(ctx context.Context, session *vtgateconn.VTGateSess } func assertTabletsPresent(t *testing.T) { - tmpCmd := exec.Command("vtctlclient", "--vtctl_client_protocol", "grpc", "--server", grpcAddress, "--stderrthreshold", "0", "ListAllTablets", "--", "test") + tmpCmd := exec.Command("vtctldclient", "--server", grpcAddress, "GetTablets", "--cell", "test") - log.Infof("Running vtctlclient with command: %v", tmpCmd.Args) + log.Infof("Running vtctldclient with command: %v", tmpCmd.Args) output, err := tmpCmd.CombinedOutput() require.Nil(t, err) diff --git a/go/test/endtoend/vtcombo/vttest_sample_test.go b/go/test/endtoend/vtcombo/vttest_sample_test.go index 4895c1195b0..af0decca3d3 100644 --- a/go/test/endtoend/vtcombo/vttest_sample_test.go +++ b/go/test/endtoend/vtcombo/vttest_sample_test.go @@ -238,9 +238,9 @@ func insertManyRows(ctx context.Context, t *testing.T, conn *vtgateconn.VTGateCo } func assertTabletsPresent(t *testing.T) { - tmpCmd := exec.Command("vtctlclient", "--vtctl_client_protocol", "grpc", "--server", grpcAddress, "--stderrthreshold", "0", "ListAllTablets", "--", "test") + tmpCmd := exec.Command("vtctldclient", "--server", grpcAddress, "GetTablets", "--cell", "test") - log.Infof("Running vtctlclient with command: %v", tmpCmd.Args) + log.Infof("Running vtctldclient with command: %v", tmpCmd.Args) output, err := tmpCmd.CombinedOutput() require.NoError(t, err) diff --git a/go/test/endtoend/vtgate/concurrentdml/main_test.go b/go/test/endtoend/vtgate/concurrentdml/main_test.go index 6ee5619b742..734962b0d33 100644 --- a/go/test/endtoend/vtgate/concurrentdml/main_test.go +++ b/go/test/endtoend/vtgate/concurrentdml/main_test.go @@ -66,7 +66,6 @@ INSERT INTO t1_seq (id, next_id, cache) values(0, 1, 1000); ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -108,7 +107,6 @@ func TestMain(m *testing.M) { } func TestInsertIgnoreOnLookupUniqueVindex(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -137,7 +135,6 @@ func TestInsertIgnoreOnLookupUniqueVindex(t *testing.T) { func TestOpenTxBlocksInSerial(t *testing.T) { t.Skip("Update and Insert in same transaction does not work with the unique consistent lookup having same value.") - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -169,7 +166,6 @@ func TestOpenTxBlocksInSerial(t *testing.T) { func TestOpenTxBlocksInConcurrent(t *testing.T) { t.Skip("Update and Insert in same transaction does not work with the unique consistent lookup having same value.") - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -207,7 +203,6 @@ func TestOpenTxBlocksInConcurrent(t *testing.T) { } func TestUpdateLookupUniqueVindex(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", diff --git a/go/test/endtoend/vtgate/connectiondrain/main_test.go b/go/test/endtoend/vtgate/connectiondrain/main_test.go index 6dae9b72be9..6257baf8e40 100644 --- a/go/test/endtoend/vtgate/connectiondrain/main_test.go +++ b/go/test/endtoend/vtgate/connectiondrain/main_test.go @@ -40,7 +40,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() os.Exit(m.Run()) } @@ -87,7 +86,6 @@ func start(t *testing.T, vtParams mysql.ConnParams) (*mysql.Conn, func()) { return vtConn, func() { deleteAll() vtConn.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/consolidator/main_test.go b/go/test/endtoend/vtgate/consolidator/main_test.go index 021db7e513e..0d5eae3eca9 100644 --- a/go/test/endtoend/vtgate/consolidator/main_test.go +++ b/go/test/endtoend/vtgate/consolidator/main_test.go @@ -65,7 +65,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index 5bfec3890b5..e2925bf928d 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -43,7 +43,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -81,7 +80,6 @@ func TestMain(m *testing.M) { } func TestDBDDLPlugin(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", diff --git a/go/test/endtoend/vtgate/errors_as_warnings/main_test.go b/go/test/endtoend/vtgate/errors_as_warnings/main_test.go index 71f4a2353f7..374a92f395f 100644 --- a/go/test/endtoend/vtgate/errors_as_warnings/main_test.go +++ b/go/test/endtoend/vtgate/errors_as_warnings/main_test.go @@ -66,7 +66,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/foreignkey/main_test.go b/go/test/endtoend/vtgate/foreignkey/main_test.go index b4d610785b5..fe418c1c0ea 100644 --- a/go/test/endtoend/vtgate/foreignkey/main_test.go +++ b/go/test/endtoend/vtgate/foreignkey/main_test.go @@ -98,7 +98,6 @@ type fkReference struct { } func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -197,7 +196,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go index 34114152e4e..42498ad80f0 100644 --- a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go +++ b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go @@ -335,7 +335,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -653,7 +652,6 @@ func ExecuteFKTest(t *testing.T, tcase *testCase) { } func TestStressFK(t *testing.T) { - defer cluster.PanicHandler(t) t.Run("validate replication health", func(t *testing.T) { validateReplicationIsHealthy(t, replicaNoFK) diff --git a/go/test/endtoend/vtgate/gen4/column_name_test.go b/go/test/endtoend/vtgate/gen4/column_name_test.go index d23c03c9f6b..0f5a83a5092 100644 --- a/go/test/endtoend/vtgate/gen4/column_name_test.go +++ b/go/test/endtoend/vtgate/gen4/column_name_test.go @@ -26,11 +26,9 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" ) func TestColumnNames(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) diff --git a/go/test/endtoend/vtgate/gen4/main_test.go b/go/test/endtoend/vtgate/gen4/main_test.go index 4c94e8e2ec8..4012017b0c3 100644 --- a/go/test/endtoend/vtgate/gen4/main_test.go +++ b/go/test/endtoend/vtgate/gen4/main_test.go @@ -61,10 +61,13 @@ var ( } ]} ` + unsharded2Ks = "uks2" + + //go:embed unsharded2_schema.sql + unsharded2SchemaSQL string ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -101,6 +104,17 @@ func TestMain(m *testing.M) { return 1 } + // This keyspace is used to test automatic addition of tables to global routing rules when + // there are multiple unsharded keyspaces. + uKs2 := &cluster.Keyspace{ + Name: unsharded2Ks, + SchemaSQL: unsharded2SchemaSQL, + } + err = clusterInstance.StartUnshardedKeyspace(*uKs2, 0, false) + if err != nil { + return 1 + } + // apply routing rules err = clusterInstance.VtctldClientProcess.ApplyRoutingRules(routingRules) if err != nil { @@ -152,6 +166,5 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/gen4/system_schema_test.go b/go/test/endtoend/vtgate/gen4/system_schema_test.go index fc4983935e9..d01d4d972a1 100644 --- a/go/test/endtoend/vtgate/gen4/system_schema_test.go +++ b/go/test/endtoend/vtgate/gen4/system_schema_test.go @@ -28,11 +28,9 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" ) func TestDbNameOverride(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.Nil(t, err) @@ -55,7 +53,6 @@ func TestDbNameOverride(t *testing.T) { } func TestInformationSchemaQuery(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -90,7 +87,6 @@ func assertSingleRowIsReturned(t *testing.T, conn *mysql.Conn, predicate string, } func TestInformationSchemaWithSubquery(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -101,7 +97,6 @@ func TestInformationSchemaWithSubquery(t *testing.T) { } func TestInformationSchemaQueryGetsRoutedToTheRightTableAndKeyspace(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -113,7 +108,6 @@ func TestInformationSchemaQueryGetsRoutedToTheRightTableAndKeyspace(t *testing.T } func TestFKConstraintUsingInformationSchema(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -131,7 +125,6 @@ func TestFKConstraintUsingInformationSchema(t *testing.T) { } func TestConnectWithSystemSchema(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() for _, dbname := range []string{"information_schema", "mysql", "performance_schema", "sys"} { connParams := vtParams @@ -144,7 +137,6 @@ func TestConnectWithSystemSchema(t *testing.T) { } func TestUseSystemSchema(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -156,7 +148,6 @@ func TestUseSystemSchema(t *testing.T) { } func TestSystemSchemaQueryWithoutQualifier(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -191,7 +182,6 @@ func TestSystemSchemaQueryWithoutQualifier(t *testing.T) { } func TestMultipleSchemaPredicates(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -217,7 +207,6 @@ func TestMultipleSchemaPredicates(t *testing.T) { } func TestQuerySystemTables(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) diff --git a/go/test/endtoend/vtgate/gen4/unsharded2_schema.sql b/go/test/endtoend/vtgate/gen4/unsharded2_schema.sql new file mode 100644 index 00000000000..c3df5bd0a56 --- /dev/null +++ b/go/test/endtoend/vtgate/gen4/unsharded2_schema.sql @@ -0,0 +1,13 @@ +create table u2_a +( + id bigint, + a bigint, + primary key (id) +) Engine = InnoDB; + +create table u2_b +( + id bigint, + b varchar(50), + primary key (id) +) Engine = InnoDB; diff --git a/go/test/endtoend/vtgate/godriver/main_test.go b/go/test/endtoend/vtgate/godriver/main_test.go index 587c189d2ea..91605394cf1 100644 --- a/go/test/endtoend/vtgate/godriver/main_test.go +++ b/go/test/endtoend/vtgate/godriver/main_test.go @@ -86,7 +86,6 @@ create table my_message( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -125,7 +124,6 @@ func TestMain(m *testing.M) { } func TestStreamMessaging(t *testing.T) { - defer cluster.PanicHandler(t) cnf := vitessdriver.Configuration{ Protocol: "grpc", diff --git a/go/test/endtoend/vtgate/grpc_api/main_test.go b/go/test/endtoend/vtgate/grpc_api/main_test.go index 3c8605f79a0..87d30f4ce26 100644 --- a/go/test/endtoend/vtgate/grpc_api/main_test.go +++ b/go/test/endtoend/vtgate/grpc_api/main_test.go @@ -75,7 +75,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode := func() int { diff --git a/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go index 4971d03060b..e3b66dd49bd 100644 --- a/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go +++ b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go @@ -46,8 +46,7 @@ var ( PRIMARY KEY (id) ) Engine=InnoDB;` vschemaDDL = "alter vschema create vindex test_vdx using hash" - vschemaDDLError = fmt.Sprintf("Error 1105 (HY000): cannot perform Update on keyspaces/%s/VSchema as the topology server connection is read-only", - keyspaceUnshardedName) + vschemaDDLError = "Error 1105 (HY000): cannot update VSchema as the topology server connection is read-only" ) // createConfig creates a config file in TmpDir in vtdataroot and writes the given data. @@ -117,7 +116,6 @@ func createCluster(extraVTGateArgs []string) (*cluster.LocalProcessCluster, int) } func TestRoutingWithKeyspacesToWatch(t *testing.T) { - defer cluster.PanicHandler(t) clusterInstance, exitCode := createCluster(nil) defer clusterInstance.Teardown() @@ -141,7 +139,6 @@ func TestRoutingWithKeyspacesToWatch(t *testing.T) { } func TestVSchemaDDLWithKeyspacesToWatch(t *testing.T) { - defer cluster.PanicHandler(t) extraVTGateArgs := []string{ "--vschema_ddl_authorized_users", "%", diff --git a/go/test/endtoend/vtgate/main_test.go b/go/test/endtoend/vtgate/main_test.go index b276508f269..6c43a70632b 100644 --- a/go/test/endtoend/vtgate/main_test.go +++ b/go/test/endtoend/vtgate/main_test.go @@ -54,7 +54,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { clusterInstance = cluster.NewCluster(Cell, "localhost") @@ -122,6 +121,5 @@ func start(t *testing.T) (*mysql.Conn, func()) { return conn, func() { deleteAll() conn.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index f3804a2a45f..b350002a05b 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -28,7 +28,6 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/sqlerror" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -754,9 +753,9 @@ func TestDescribeVindex(t *testing.T) { _, err := conn.ExecuteFetch("describe hash", 1000, false) require.Error(t, err) mysqlErr := err.(*sqlerror.SQLError) - assert.Equal(t, sqlerror.ERNoSuchTable, mysqlErr.Num) + assert.Equal(t, sqlerror.ERUnknownTable, mysqlErr.Num) assert.Equal(t, "42S02", mysqlErr.State) - assert.ErrorContains(t, mysqlErr, "NotFound desc") + assert.ErrorContains(t, mysqlErr, "VT05004: table 'hash' does not exist") } func TestEmptyQuery(t *testing.T) { @@ -783,7 +782,6 @@ func TestJoinWithMergedRouteWithPredicate(t *testing.T) { func TestRowCountExceed(t *testing.T) { conn, _ := start(t) defer func() { - cluster.PanicHandler(t) // needs special delete logic as it exceeds row count. for i := 50; i <= 300; i += 50 { utils.Exec(t, conn, fmt.Sprintf("delete from t1 where id1 < %d", i)) @@ -816,6 +814,81 @@ func TestDDLTargeted(t *testing.T) { utils.AssertMatches(t, conn, `select id from ddl_targeted`, `[[INT64(1)]]`) } +// TestDynamicConfig tests the dynamic configurations. +func TestDynamicConfig(t *testing.T) { + t.Run("DiscoveryLowReplicationLag", func(t *testing.T) { + // Test initial config value + err := clusterInstance.VtgateProcess.WaitForConfig(`"discovery_low_replication_lag":30000000000`) + require.NoError(t, err) + defer func() { + // Restore default back. + clusterInstance.VtgateProcess.Config.DiscoveryLowReplicationLag = "30s" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + }() + clusterInstance.VtgateProcess.Config.DiscoveryLowReplicationLag = "15s" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + // Test final config value. + err = clusterInstance.VtgateProcess.WaitForConfig(`"discovery_low_replication_lag":"15s"`) + require.NoError(t, err) + }) + + t.Run("DiscoveryHighReplicationLag", func(t *testing.T) { + // Test initial config value + err := clusterInstance.VtgateProcess.WaitForConfig(`"discovery_high_replication_lag":7200000000000`) + require.NoError(t, err) + defer func() { + // Restore default back. + clusterInstance.VtgateProcess.Config.DiscoveryHighReplicationLag = "2h" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + }() + clusterInstance.VtgateProcess.Config.DiscoveryHighReplicationLag = "1h" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + // Test final config value. + err = clusterInstance.VtgateProcess.WaitForConfig(`"discovery_high_replication_lag":"1h"`) + require.NoError(t, err) + }) + + t.Run("DiscoveryMinServingVttablets", func(t *testing.T) { + // Test initial config value + err := clusterInstance.VtgateProcess.WaitForConfig(`"discovery_min_number_serving_vttablets":2`) + require.NoError(t, err) + defer func() { + // Restore default back. + clusterInstance.VtgateProcess.Config.DiscoveryMinServingVttablets = "2" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + }() + clusterInstance.VtgateProcess.Config.DiscoveryMinServingVttablets = "1" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + // Test final config value. + err = clusterInstance.VtgateProcess.WaitForConfig(`"discovery_min_number_serving_vttablets":"1"`) + require.NoError(t, err) + }) + + t.Run("DiscoveryLegacyReplicationLagAlgo", func(t *testing.T) { + // Test initial config value + err := clusterInstance.VtgateProcess.WaitForConfig(`"discovery_legacy_replication_lag_algorithm":""`) + require.NoError(t, err) + defer func() { + // Restore default back. + clusterInstance.VtgateProcess.Config.DiscoveryLegacyReplicationLagAlgo = "true" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + }() + clusterInstance.VtgateProcess.Config.DiscoveryLegacyReplicationLagAlgo = "false" + err = clusterInstance.VtgateProcess.RewriteConfiguration() + require.NoError(t, err) + // Test final config value. + err = clusterInstance.VtgateProcess.WaitForConfig(`"discovery_legacy_replication_lag_algorithm":"false"`) + require.NoError(t, err) + }) +} + func TestLookupErrorMetric(t *testing.T) { conn, closer := start(t) defer closer() diff --git a/go/test/endtoend/vtgate/mysql80/main_test.go b/go/test/endtoend/vtgate/mysql80/main_test.go index 4f5897d1f59..b970fb66b12 100644 --- a/go/test/endtoend/vtgate/mysql80/main_test.go +++ b/go/test/endtoend/vtgate/mysql80/main_test.go @@ -35,7 +35,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/mysql80/misc_test.go b/go/test/endtoend/vtgate/mysql80/misc_test.go index b29eb13ecdc..5132bf87aba 100644 --- a/go/test/endtoend/vtgate/mysql80/misc_test.go +++ b/go/test/endtoend/vtgate/mysql80/misc_test.go @@ -23,15 +23,12 @@ import ( "vitess.io/vitess/go/test/endtoend/utils" - "vitess.io/vitess/go/test/endtoend/cluster" - "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" ) func TestFunctionInDefault(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -223,7 +220,6 @@ func BenchmarkReservedConnWhenSettingSysVar(b *testing.B) { } func TestJsonFunctions(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) diff --git a/go/test/endtoend/vtgate/partialfailure/main_test.go b/go/test/endtoend/vtgate/partialfailure/main_test.go index 9e39e7b5dd5..d5b6a639c68 100644 --- a/go/test/endtoend/vtgate/partialfailure/main_test.go +++ b/go/test/endtoend/vtgate/partialfailure/main_test.go @@ -45,7 +45,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/plan_tests/main_test.go b/go/test/endtoend/vtgate/plan_tests/main_test.go new file mode 100644 index 00000000000..2dc2e70120b --- /dev/null +++ b/go/test/endtoend/vtgate/plan_tests/main_test.go @@ -0,0 +1,257 @@ +/* +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 plan_tests + +import ( + "encoding/json" + "fmt" + "os" + "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" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vtgate/planbuilder" +) + +var ( + clusterInstance *cluster.LocalProcessCluster + vtParams mysql.ConnParams + mysqlParams mysql.ConnParams + uks = "main" + sks = "user" + cell = "plantests" +) + +func TestMain(m *testing.M) { + vschema := readFile("vschemas/schema.json") + userVs := extractUserKS(vschema) + mainVs := extractMainKS(vschema) + sSQL := readFile("schemas/user.sql") + uSQL := readFile("schemas/main.sql") + + exitCode := func() int { + clusterInstance = cluster.NewCluster(cell, "localhost") + defer clusterInstance.Teardown() + + // Start topo server + err := clusterInstance.StartTopo() + if err != nil { + fmt.Println(err.Error()) + return 1 + } + + // Start unsharded keyspace + uKeyspace := &cluster.Keyspace{ + Name: uks, + SchemaSQL: uSQL, + VSchema: mainVs, + } + err = clusterInstance.StartUnshardedKeyspace(*uKeyspace, 0, false) + if err != nil { + fmt.Println(err.Error()) + return 1 + } + + // Start sharded keyspace + skeyspace := &cluster.Keyspace{ + Name: sks, + SchemaSQL: sSQL, + VSchema: userVs, + } + err = clusterInstance.StartKeyspace(*skeyspace, []string{"-80", "80-"}, 0, false) + if err != nil { + fmt.Println(err.Error()) + return 1 + } + + // TODO: (@GuptaManan100/@systay): Also run the tests with normalizer on. + clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, + "--normalize_queries=false", + "--schema_change_signal=true", + ) + + // Start vtgate + err = clusterInstance.StartVtgate() + if err != nil { + fmt.Println(err.Error()) + return 1 + } + + vtParams = clusterInstance.GetVTParams(sks) + + // create mysql instance and connection parameters + conn, closer, err := utils.NewMySQL(clusterInstance, sks, sSQL, uSQL) + if err != nil { + fmt.Println(err.Error()) + return 1 + } + defer closer() + mysqlParams = conn + + return m.Run() + }() + os.Exit(exitCode) +} + +func readFile(filename string) string { + schema, err := os.ReadFile(locateFile(filename)) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + return string(schema) +} + +func start(t *testing.T) (utils.MySQLCompare, func()) { + mcmp, err := utils.NewMySQLCompare(t, vtParams, mysqlParams) + require.NoError(t, err) + return mcmp, func() { + mcmp.Close() + } +} + +// splitSQL statements - querySQL may be a multi-line sql blob +func splitSQL(querySQL ...string) ([]string, error) { + parser := sqlparser.NewTestParser() + var sqls []string + for _, sql := range querySQL { + split, err := parser.SplitStatementToPieces(sql) + if err != nil { + return nil, err + } + sqls = append(sqls, split...) + } + return sqls, nil +} + +func loadSampleData(t *testing.T, mcmp utils.MySQLCompare) { + sampleDataSQL := readFile("sampledata/user.sql") + insertSQL, err := splitSQL(sampleDataSQL) + if err != nil { + require.NoError(t, err) + } + for _, sql := range insertSQL { + mcmp.ExecNoCompare(sql) + } +} + +func readJSONTests(filename string) []planbuilder.PlanTest { + var output []planbuilder.PlanTest + file, err := os.Open(locateFile(filename)) + if err != nil { + panic(err) + } + defer file.Close() + dec := json.NewDecoder(file) + err = dec.Decode(&output) + if err != nil { + panic(err) + } + return output +} + +func locateFile(name string) string { + return "../../../../vt/vtgate/planbuilder/testdata/" + name +} + +// verifyTestExpectations verifies the expectations of the test. +func verifyTestExpectations(t *testing.T, pd engine.PrimitiveDescription, test planbuilder.PlanTest) { + // 1. Verify that the Join primitive sees atleast 1 row on the left side. + engine.WalkPrimitiveDescription(pd, func(description engine.PrimitiveDescription) { + if description.OperatorType == "Join" { + assert.NotZero(t, description.Inputs[0].RowsReceived[0]) + } + }) + + // 2. Verify that the plan description matches the expected plan description. + planBytes, err := test.Plan.MarshalJSON() + require.NoError(t, err) + mp := make(map[string]any) + err = json.Unmarshal(planBytes, &mp) + require.NoError(t, err) + pdExpected, err := engine.PrimitiveDescriptionFromMap(mp["Instructions"].(map[string]any)) + require.NoError(t, err) + require.Empty(t, pdExpected.Equals(pd), "Expected: %v\nGot: %v", string(planBytes), pd) +} + +func extractUserKS(jsonString string) string { + var result map[string]any + if err := json.Unmarshal([]byte(jsonString), &result); err != nil { + panic(err.Error()) + } + + keyspaces, ok := result["keyspaces"].(map[string]any) + if !ok { + panic("Keyspaces not found") + } + + user, ok := keyspaces["user"].(map[string]any) + if !ok { + panic("User keyspace not found") + } + + tables, ok := user["tables"].(map[string]any) + if !ok { + panic("Tables not found") + } + + userTbl, ok := tables["user"].(map[string]any) + if !ok { + panic("User table not found") + } + + delete(userTbl, "auto_increment") // TODO: we should have an unsharded keyspace where this could live + + // Marshal the inner part back to JSON string + userJson, err := json.Marshal(user) + if err != nil { + panic(err.Error()) + } + + return string(userJson) +} + +func extractMainKS(jsonString string) string { + var result map[string]any + if err := json.Unmarshal([]byte(jsonString), &result); err != nil { + panic(err.Error()) + } + + keyspaces, ok := result["keyspaces"].(map[string]any) + if !ok { + panic("Keyspaces not found") + } + + main, ok := keyspaces["main"].(map[string]any) + if !ok { + panic("main keyspace not found") + } + + // Marshal the inner part back to JSON string + mainJson, err := json.Marshal(main) + if err != nil { + panic(err.Error()) + } + + return string(mainJson) +} diff --git a/go/test/endtoend/vtgate/plan_tests/plan_e2e_test.go b/go/test/endtoend/vtgate/plan_tests/plan_e2e_test.go new file mode 100644 index 00000000000..0068616c3b8 --- /dev/null +++ b/go/test/endtoend/vtgate/plan_tests/plan_e2e_test.go @@ -0,0 +1,61 @@ +/* +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 plan_tests + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/sqlparser" +) + +func TestE2ECases(t *testing.T) { + err := utils.WaitForAuthoritative(t, "main", "source_of_ref", clusterInstance.VtgateProcess.ReadVSchema) + require.NoError(t, err) + + e2eTestCaseFiles := []string{ + "select_cases.json", + "filter_cases.json", + "dml_cases.json", + "reference_cases.json", + } + mcmp, closer := start(t) + defer closer() + loadSampleData(t, mcmp) + for _, fileName := range e2eTestCaseFiles { + tests := readJSONTests(fileName) + for _, test := range tests { + mcmp.Run(test.Comment, func(mcmp *utils.MySQLCompare) { + if test.SkipE2E { + mcmp.AsT().Skip(test.Query) + } + stmt, err := sqlparser.NewTestParser().Parse(test.Query) + require.NoError(mcmp.AsT(), err) + sqlparser.RemoveKeyspaceIgnoreSysSchema(stmt) + + mcmp.ExecVitessAndMySQLDifferentQueries(test.Query, sqlparser.String(stmt)) + pd := utils.ExecTrace(mcmp.AsT(), mcmp.VtConn, test.Query) + verifyTestExpectations(mcmp.AsT(), pd, test) + if mcmp.VtConn.IsClosed() { + mcmp.AsT().Fatal("vtgate connection is closed") + } + }) + } + } +} diff --git a/go/test/endtoend/vtgate/prefixfanout/main_test.go b/go/test/endtoend/vtgate/prefixfanout/main_test.go index 928808fd48e..a96ee4ce7f5 100644 --- a/go/test/endtoend/vtgate/prefixfanout/main_test.go +++ b/go/test/endtoend/vtgate/prefixfanout/main_test.go @@ -109,7 +109,6 @@ PRIMARY KEY (c1) ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -158,7 +157,6 @@ func TestMain(m *testing.M) { } func TestCFCPrefixQueryNoHash(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := clusterInstance.GetVTParams(sKs) conn, err := mysql.Connect(ctx, &vtParams) @@ -196,7 +194,6 @@ func TestCFCPrefixQueryNoHash(t *testing.T) { } func TestCFCPrefixQueryWithHash(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := clusterInstance.GetVTParams(sKsMD5) @@ -239,7 +236,6 @@ func TestCFCPrefixQueryWithHash(t *testing.T) { } func TestCFCInsert(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := clusterInstance.GetVTParams(sKs) diff --git a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go index d206f58e17c..62d23749cd7 100644 --- a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go +++ b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go @@ -27,7 +27,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -66,7 +65,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/aggregation/main_test.go b/go/test/endtoend/vtgate/queries/aggregation/main_test.go index 02013a9b0e2..bd1c1aa3b7d 100644 --- a/go/test/endtoend/vtgate/queries/aggregation/main_test.go +++ b/go/test/endtoend/vtgate/queries/aggregation/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/benchmark/main_test.go b/go/test/endtoend/vtgate/queries/benchmark/main_test.go index 40a215c8007..0410f52993a 100644 --- a/go/test/endtoend/vtgate/queries/benchmark/main_test.go +++ b/go/test/endtoend/vtgate/queries/benchmark/main_test.go @@ -65,7 +65,6 @@ var shards4 = []string{ } func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -169,6 +168,5 @@ func start(b *testing.B) (*mysql.Conn, func()) { return conn, func() { deleteAll() conn.Close() - cluster.PanicHandler(b) } } diff --git a/go/test/endtoend/vtgate/queries/derived/derived_test.go b/go/test/endtoend/vtgate/queries/derived/derived_test.go index cb106564b2f..fe467f31c20 100644 --- a/go/test/endtoend/vtgate/queries/derived/derived_test.go +++ b/go/test/endtoend/vtgate/queries/derived/derived_test.go @@ -21,7 +21,6 @@ import ( "github.com/stretchr/testify/require" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -44,7 +43,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/derived/main_test.go b/go/test/endtoend/vtgate/queries/derived/main_test.go index 3b44811f95c..0bab24a966a 100644 --- a/go/test/endtoend/vtgate/queries/derived/main_test.go +++ b/go/test/endtoend/vtgate/queries/derived/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/dml/main_test.go b/go/test/endtoend/vtgate/queries/dml/main_test.go index 0c4d58aa614..bc72acc1159 100644 --- a/go/test/endtoend/vtgate/queries/dml/main_test.go +++ b/go/test/endtoend/vtgate/queries/dml/main_test.go @@ -66,7 +66,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -148,6 +147,5 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/foundrows/found_rows_test.go b/go/test/endtoend/vtgate/queries/foundrows/found_rows_test.go index f52e2eff532..e50e9210c55 100644 --- a/go/test/endtoend/vtgate/queries/foundrows/found_rows_test.go +++ b/go/test/endtoend/vtgate/queries/foundrows/found_rows_test.go @@ -21,12 +21,10 @@ import ( "github.com/stretchr/testify/require" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) func TestFoundRows(t *testing.T) { - defer cluster.PanicHandler(t) mcmp, err := utils.NewMySQLCompare(t, vtParams, mysqlParams) require.NoError(t, err) defer mcmp.Close() diff --git a/go/test/endtoend/vtgate/queries/foundrows/main_test.go b/go/test/endtoend/vtgate/queries/foundrows/main_test.go index 8f992863008..248b6cd9434 100644 --- a/go/test/endtoend/vtgate/queries/foundrows/main_test.go +++ b/go/test/endtoend/vtgate/queries/foundrows/main_test.go @@ -46,7 +46,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go b/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go index c5568b2db49..e158bd96e33 100644 --- a/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go +++ b/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go @@ -25,7 +25,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -47,7 +46,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } @@ -114,7 +112,6 @@ func TestFKConstraintUsingInformationSchema(t *testing.T) { } func TestConnectWithSystemSchema(t *testing.T) { - defer cluster.PanicHandler(t) for _, dbname := range []string{"information_schema", "mysql", "performance_schema", "sys"} { vtConnParams := vtParams vtConnParams.DbName = dbname diff --git a/go/test/endtoend/vtgate/queries/informationschema/main_test.go b/go/test/endtoend/vtgate/queries/informationschema/main_test.go index 3696617281e..76d5f44ebae 100644 --- a/go/test/endtoend/vtgate/queries/informationschema/main_test.go +++ b/go/test/endtoend/vtgate/queries/informationschema/main_test.go @@ -52,7 +52,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/kill/main_test.go b/go/test/endtoend/vtgate/queries/kill/main_test.go index 99608030246..61ddec43589 100644 --- a/go/test/endtoend/vtgate/queries/kill/main_test.go +++ b/go/test/endtoend/vtgate/queries/kill/main_test.go @@ -50,7 +50,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/lookup_queries/main_test.go b/go/test/endtoend/vtgate/queries/lookup_queries/main_test.go index a587f124762..818b834511a 100644 --- a/go/test/endtoend/vtgate/queries/lookup_queries/main_test.go +++ b/go/test/endtoend/vtgate/queries/lookup_queries/main_test.go @@ -49,7 +49,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -119,7 +118,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/misc/main_test.go b/go/test/endtoend/vtgate/queries/misc/main_test.go index f20072031a8..536dfa7500a 100644 --- a/go/test/endtoend/vtgate/queries/misc/main_test.go +++ b/go/test/endtoend/vtgate/queries/misc/main_test.go @@ -48,7 +48,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -96,7 +95,7 @@ func TestMain(m *testing.M) { vtParams = clusterInstance.GetVTParams(keyspaceName) // create mysql instance and connection parameters - conn, closer, err := utils.NewMySQL(clusterInstance, keyspaceName, schemaSQL) + conn, closer, err := utils.NewMySQL(clusterInstance, keyspaceName, schemaSQL, uschemaSQL) if err != nil { fmt.Println(err) return 1 diff --git a/go/test/endtoend/vtgate/queries/misc/misc_test.go b/go/test/endtoend/vtgate/queries/misc/misc_test.go index fd869c4ba5b..7ab0fe7ef54 100644 --- a/go/test/endtoend/vtgate/queries/misc/misc_test.go +++ b/go/test/endtoend/vtgate/queries/misc/misc_test.go @@ -25,12 +25,12 @@ import ( "time" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/sqlparser" _ "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -50,7 +50,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } @@ -133,6 +132,153 @@ func TestCast(t *testing.T) { mcmp.AssertMatches("select cast('3.2' as unsigned)", `[[UINT64(3)]]`) } +// TestSetAndGetLastInsertID tests that the last_insert_id function works as intended when used with different arguments. +func TestSetAndGetLastInsertID(t *testing.T) { + notZero := 1 + checkQuery := func(i string, workload string, tx bool, mcmp utils.MySQLCompare) { + for _, val := range []int{notZero, 0, notZero * 2} { + query := fmt.Sprintf(i, val) + name := fmt.Sprintf("%s - %s", workload, query) + if tx { + name = "tx - " + name + } + mcmp.Run(name, func(mcmp *utils.MySQLCompare) { + mcmp.Exec(query) + mcmp.Exec("select last_insert_id()") + t := mcmp.AsT() + if t.Failed() { + t.Log(mcmp.VExplain(query)) + } + }) + } + // we need this value to be not zero, and then we keep changing it so different queries don't interact with each other + notZero++ + } + + queries := []string{ + "select last_insert_id(%d)", + "select last_insert_id(%d), id1, id2 from t1 limit 1", + "select last_insert_id(%d), id1, id2 from t1 where 1 = 2", + "select 12 from t1 where last_insert_id(%d)", + "update t1 set id2 = last_insert_id(%d) where id1 = 1", + "update t1 set id2 = last_insert_id(%d) where id1 = 2", + "update t1 set id2 = 88 where id1 = last_insert_id(%d)", + "delete from t1 where id1 = last_insert_id(%d)", + "select id2, last_insert_id(count(*)) from t1 where %d group by id2", + "set @x = last_insert_id(%d)", + } + + for _, workload := range []string{"olap", "oltp"} { + for _, tx := range []bool{true, false} { + mcmp, closer := start(t) + _, err := mcmp.VtConn.ExecuteFetch(fmt.Sprintf("set workload = %s", workload), 1000, false) + require.NoError(t, err) + if tx { + _, err := mcmp.VtConn.ExecuteFetch("begin", 1000, false) + require.NoError(t, err) + } + + // Insert a few rows for UPDATE tests + mcmp.Exec("insert into t1 (id1, id2) values (1, 10)") + + for _, query := range queries { + checkQuery(query, workload, tx, mcmp) + } + closer() + } + } +} + +func TestSetAndGetLastInsertIDWithInsertUnsharded(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + tests := []string{ + "insert into uks.unsharded(id1, id2) values (last_insert_id(%d),12)", + "insert into uks.unsharded(id1, id2) select last_insert_id(%d), 453", + } + + i := 0 + getVal := func() int { + defer func() { i++ }() + return i + } + + runTests := func(mcmp *utils.MySQLCompare) { + for _, test := range tests { + + lastInsertID := getVal() + query := fmt.Sprintf(test, lastInsertID) + + stmt, err := sqlparser.NewTestParser().Parse(query) + require.NoError(mcmp.AsT(), err) + sqlparser.RemoveKeyspaceIgnoreSysSchema(stmt) + + mcmp.ExecVitessAndMySQLDifferentQueries(query, sqlparser.String(stmt)) + mcmp.Exec("select last_insert_id()") + } + } + + for _, workload := range []string{"olap", "oltp"} { + mcmp.Run(workload, func(mcmp *utils.MySQLCompare) { + _, err := mcmp.VtConn.ExecuteFetch("set workload = "+workload, 1, false) + require.NoError(t, err) + runTests(mcmp) + + // run the queries again, but inside a transaction this time + mcmp.Exec("begin") + runTests(mcmp) + mcmp.Exec("commit") + }) + } + + // Now test to set the last insert id to 0, see that it has changed correctly even if the value is 0 + mcmp.ExecVitessAndMySQLDifferentQueries( + "insert into uks.unsharded(id1, id2) values (last_insert_id(0),12)", + "insert into unsharded(id1, id2) values (last_insert_id(0),12)", + ) + mcmp.Exec("select last_insert_id()") +} + +func TestSetAndGetLastInsertIDWithInsert(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + tests := []string{ + "insert into t1(id1, id2) values (last_insert_id(%d) ,%d)", + "insert into t1(id1, id2) values (%d, last_insert_id(%d))", + "insert into t1(id1, id2) select last_insert_id(%d), %d", + "insert into t1(id1, id2) select last_insert_id(id1+%d), 12 from t1 where 1 > %d", + } + + i := 0 + getVal := func() int { + defer func() { i++ }() + return i + } + + runTests := func(mcmp *utils.MySQLCompare) { + for _, test := range tests { + query := fmt.Sprintf(test, getVal(), getVal()) + mcmp.Exec(query) + mcmp.Exec("select last_insert_id()") + } + } + + for _, workload := range []string{"olap", "oltp"} { + mcmp.Run(workload, func(mcmp *utils.MySQLCompare) { + _, err := mcmp.VtConn.ExecuteFetch("set workload = "+workload, 1, false) + require.NoError(t, err) + runTests(mcmp) + + // run the queries again, but inside a transaction this time + mcmp.Exec("begin") + runTests(mcmp) + mcmp.Exec("commit") + }) + } +} + // TestVindexHints tests that vindex hints work as intended. func TestVindexHints(t *testing.T) { mcmp, closer := start(t) @@ -521,3 +667,23 @@ func TestTimeZones(t *testing.T) { }) } } + +// TestSemiJoin tests that the semi join works as intended. +func TestSemiJoin(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + for i := 1; i <= 1000; i++ { + mcmp.Exec(fmt.Sprintf("insert into t1(id1, id2) values (%d, %d)", i, 2*i)) + mcmp.Exec(fmt.Sprintf("insert into tbl(id, unq_col, nonunq_col) values (%d, %d, %d)", i, 2*i, 3*i)) + } + + // Test that the semi join works as intended + for _, mode := range []string{"oltp", "olap"} { + mcmp.Run(mode, func(mcmp *utils.MySQLCompare) { + utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = %s", mode)) + + mcmp.Exec("select id1, id2 from t1 where exists (select id from tbl where nonunq_col = t1.id2) order by id1") + }) + } +} diff --git a/go/test/endtoend/vtgate/queries/no_scatter/main_test.go b/go/test/endtoend/vtgate/queries/no_scatter/main_test.go index c4b0974c24b..a1478dcd2ac 100644 --- a/go/test/endtoend/vtgate/queries/no_scatter/main_test.go +++ b/go/test/endtoend/vtgate/queries/no_scatter/main_test.go @@ -40,7 +40,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/no_scatter/queries_test.go b/go/test/endtoend/vtgate/queries/no_scatter/queries_test.go index 7bf702afc15..b302a0f4dc7 100644 --- a/go/test/endtoend/vtgate/queries/no_scatter/queries_test.go +++ b/go/test/endtoend/vtgate/queries/no_scatter/queries_test.go @@ -23,7 +23,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -43,7 +42,6 @@ func start(t *testing.T) (*mysql.Conn, func()) { return vtConn, func() { deleteAll() vtConn.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/normalize/main_test.go b/go/test/endtoend/vtgate/queries/normalize/main_test.go index 8f4d97209dd..8c75d38284d 100644 --- a/go/test/endtoend/vtgate/queries/normalize/main_test.go +++ b/go/test/endtoend/vtgate/queries/normalize/main_test.go @@ -39,7 +39,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/orderby/main_test.go b/go/test/endtoend/vtgate/queries/orderby/main_test.go index 9f18377ee3f..353745722b7 100644 --- a/go/test/endtoend/vtgate/queries/orderby/main_test.go +++ b/go/test/endtoend/vtgate/queries/orderby/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/orderby/orderby_test.go b/go/test/endtoend/vtgate/queries/orderby/orderby_test.go index c36b52a4e6a..716f01fb5c7 100644 --- a/go/test/endtoend/vtgate/queries/orderby/orderby_test.go +++ b/go/test/endtoend/vtgate/queries/orderby/orderby_test.go @@ -22,8 +22,6 @@ import ( "vitess.io/vitess/go/test/endtoend/utils" "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/test/endtoend/cluster" ) func start(t *testing.T) (utils.MySQLCompare, func()) { @@ -44,7 +42,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/orderby/without_schematracker/main_test.go b/go/test/endtoend/vtgate/queries/orderby/without_schematracker/main_test.go index 00221e9c9f3..373c1327074 100644 --- a/go/test/endtoend/vtgate/queries/orderby/without_schematracker/main_test.go +++ b/go/test/endtoend/vtgate/queries/orderby/without_schematracker/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/orderby/without_schematracker/orderby_test.go b/go/test/endtoend/vtgate/queries/orderby/without_schematracker/orderby_test.go index a20c7ad54c6..956815d2a0d 100644 --- a/go/test/endtoend/vtgate/queries/orderby/without_schematracker/orderby_test.go +++ b/go/test/endtoend/vtgate/queries/orderby/without_schematracker/orderby_test.go @@ -22,8 +22,6 @@ import ( "vitess.io/vitess/go/test/endtoend/utils" "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/test/endtoend/cluster" ) func start(t *testing.T) (utils.MySQLCompare, func()) { @@ -44,7 +42,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/random/main_test.go b/go/test/endtoend/vtgate/queries/random/main_test.go index e3256f60796..85c8840924d 100644 --- a/go/test/endtoend/vtgate/queries/random/main_test.go +++ b/go/test/endtoend/vtgate/queries/random/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/random/query_gen.go b/go/test/endtoend/vtgate/queries/random/query_gen.go index ba7c83aaa91..69bf66903f3 100644 --- a/go/test/endtoend/vtgate/queries/random/query_gen.go +++ b/go/test/endtoend/vtgate/queries/random/query_gen.go @@ -46,7 +46,7 @@ type ( // queryGenerator generates queries, which can either be unions or select statements queryGenerator struct { - stmt sqlparser.SelectStatement + stmt sqlparser.TableStatement selGen *selectGenerator } diff --git a/go/test/endtoend/vtgate/queries/random/random_test.go b/go/test/endtoend/vtgate/queries/random/random_test.go index 2d210ee7f99..20c7934d91f 100644 --- a/go/test/endtoend/vtgate/queries/random/random_test.go +++ b/go/test/endtoend/vtgate/queries/random/random_test.go @@ -27,7 +27,6 @@ import ( "github.com/stretchr/testify/require" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -61,7 +60,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/random/simplifier_test.go b/go/test/endtoend/vtgate/queries/random/simplifier_test.go index c93c0e679c1..4305124e23c 100644 --- a/go/test/endtoend/vtgate/queries/random/simplifier_test.go +++ b/go/test/endtoend/vtgate/queries/random/simplifier_test.go @@ -100,10 +100,10 @@ func simplifyResultsMismatchedQuery(t *testing.T, query string) string { require.NoError(t, err) simplified := simplifier.SimplifyStatement( - stmt.(sqlparser.SelectStatement), + stmt.(sqlparser.TableStatement), vSchemaWrapper.CurrentDb(), vSchemaWrapper, - func(statement sqlparser.SelectStatement) bool { + func(statement sqlparser.TableStatement) bool { q := sqlparser.String(statement) _, newErr := mcmp.ExecAllowAndCompareError(q, utils.CompareOptions{}) if newErr == nil { diff --git a/go/test/endtoend/vtgate/queries/reference/main_test.go b/go/test/endtoend/vtgate/queries/reference/main_test.go index c350038bf6e..95e19ef596a 100644 --- a/go/test/endtoend/vtgate/queries/reference/main_test.go +++ b/go/test/endtoend/vtgate/queries/reference/main_test.go @@ -53,7 +53,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -156,24 +155,14 @@ func TestMain(m *testing.M) { }() // Materialize zip_detail to sharded keyspace. - output, err := clusterInstance.VtctlProcess.ExecuteCommandWithOutput( + output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput( "Materialize", - "--", - "--tablet_types", - "PRIMARY", - `{ - "workflow": "copy_zip_detail", - "source_keyspace": "`+unshardedKeyspaceName+`", - "target_keyspace": "`+shardedKeyspaceName+`", - "tablet_types": "PRIMARY", - "table_settings": [ - { - "target_table": "zip_detail", - "source_expression": "select * from zip_detail", - "create_ddl": "copy" - } - ] - }`, + "--workflow", "copy_zip_detail", + "--target-keyspace", shardedKeyspaceName, + "create", + "--source-keyspace", unshardedKeyspaceName, + "--table-settings", `[{"target_table": "zip_detail", "source_expression": "select * from zip_detail", "create_ddl": "copy" }]`, + "--tablet-types", "PRIMARY", ) fmt.Fprintf(os.Stderr, "Output from materialize: %s\n", output) if err != nil { @@ -215,11 +204,12 @@ func TestMain(m *testing.M) { } // Stop materialize zip_detail to sharded keyspace. - err = clusterInstance.VtctlProcess.ExecuteCommand( + err = clusterInstance.VtctldClientProcess.ExecuteCommand( "Workflow", - "--", - shardedKeyspaceName+".copy_zip_detail", + "--keyspace", shardedKeyspaceName, "delete", + "--workflow", "copy_zip_detail", + "--keep-data", ) if err != nil { fmt.Fprintf(os.Stderr, "Failed to stop materialization workflow: %v", err) diff --git a/go/test/endtoend/vtgate/queries/reference/reference_test.go b/go/test/endtoend/vtgate/queries/reference/reference_test.go index 66d46dfaf15..ce942833729 100644 --- a/go/test/endtoend/vtgate/queries/reference/reference_test.go +++ b/go/test/endtoend/vtgate/queries/reference/reference_test.go @@ -24,8 +24,6 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/utils" - - "vitess.io/vitess/go/test/endtoend/cluster" ) func start(t *testing.T) (*mysql.Conn, func()) { @@ -35,7 +33,6 @@ func start(t *testing.T) (*mysql.Conn, func()) { return vtConn, func() { vtConn.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/subquery/main_test.go b/go/test/endtoend/vtgate/queries/subquery/main_test.go index 9eaf3b4caa0..bc8580bd38d 100644 --- a/go/test/endtoend/vtgate/queries/subquery/main_test.go +++ b/go/test/endtoend/vtgate/queries/subquery/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go index 4298bbe80fc..135b86195a5 100644 --- a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go +++ b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go @@ -25,7 +25,6 @@ import ( "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -47,7 +46,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/timeout/main_test.go b/go/test/endtoend/vtgate/queries/timeout/main_test.go index 06e8a786469..81fcfb26095 100644 --- a/go/test/endtoend/vtgate/queries/timeout/main_test.go +++ b/go/test/endtoend/vtgate/queries/timeout/main_test.go @@ -48,7 +48,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/timeout/timeout_test.go b/go/test/endtoend/vtgate/queries/timeout/timeout_test.go index 565c3c07a4f..d1d718add25 100644 --- a/go/test/endtoend/vtgate/queries/timeout/timeout_test.go +++ b/go/test/endtoend/vtgate/queries/timeout/timeout_test.go @@ -25,7 +25,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -45,7 +44,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/tpch/main_test.go b/go/test/endtoend/vtgate/queries/tpch/main_test.go index 103adb336ab..403ddd510ce 100644 --- a/go/test/endtoend/vtgate/queries/tpch/main_test.go +++ b/go/test/endtoend/vtgate/queries/tpch/main_test.go @@ -43,7 +43,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/tpch/tpch_test.go b/go/test/endtoend/vtgate/queries/tpch/tpch_test.go index c4bf71cafa1..efa322a5e1c 100644 --- a/go/test/endtoend/vtgate/queries/tpch/tpch_test.go +++ b/go/test/endtoend/vtgate/queries/tpch/tpch_test.go @@ -21,7 +21,6 @@ import ( "github.com/stretchr/testify/require" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) @@ -43,7 +42,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/union/main_test.go b/go/test/endtoend/vtgate/queries/union/main_test.go index 06ec07a6c2f..a5f45f84156 100644 --- a/go/test/endtoend/vtgate/queries/union/main_test.go +++ b/go/test/endtoend/vtgate/queries/union/main_test.go @@ -43,7 +43,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/union/union_test.go b/go/test/endtoend/vtgate/queries/union/union_test.go index 03f98950f44..26371af3c87 100644 --- a/go/test/endtoend/vtgate/queries/union/union_test.go +++ b/go/test/endtoend/vtgate/queries/union/union_test.go @@ -19,7 +19,6 @@ package union import ( "testing" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" "github.com/stretchr/testify/assert" @@ -44,7 +43,6 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { return mcmp, func() { deleteAll() mcmp.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/queries/vexplain/main_test.go b/go/test/endtoend/vtgate/queries/vexplain/main_test.go index c1c401bc573..96b6a1c41d1 100644 --- a/go/test/endtoend/vtgate/queries/vexplain/main_test.go +++ b/go/test/endtoend/vtgate/queries/vexplain/main_test.go @@ -43,7 +43,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/queries/vexplain/vexplain_test.go b/go/test/endtoend/vtgate/queries/vexplain/vexplain_test.go index 45baf7af903..1a8ec2b4c37 100644 --- a/go/test/endtoend/vtgate/queries/vexplain/vexplain_test.go +++ b/go/test/endtoend/vtgate/queries/vexplain/vexplain_test.go @@ -24,7 +24,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/utils" @@ -49,7 +48,6 @@ func start(t *testing.T) (*mysql.Conn, func()) { return vtConn, func() { deleteAll() vtConn.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/readafterwrite/raw_test.go b/go/test/endtoend/vtgate/readafterwrite/raw_test.go index 0549a9b06b0..ce6db45d24e 100644 --- a/go/test/endtoend/vtgate/readafterwrite/raw_test.go +++ b/go/test/endtoend/vtgate/readafterwrite/raw_test.go @@ -100,7 +100,6 @@ CREATE TABLE test_vdx ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -143,7 +142,6 @@ func TestMain(m *testing.M) { } func TestRAWSettings(t *testing.T) { - defer cluster.PanicHandler(t) conn, err := mysql.Connect(context.Background(), &vtParams) require.NoError(t, err) defer conn.Close() diff --git a/go/test/endtoend/vtgate/reservedconn/main_test.go b/go/test/endtoend/vtgate/reservedconn/main_test.go index 8c0278604f7..00f569d9eb9 100644 --- a/go/test/endtoend/vtgate/reservedconn/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/main_test.go @@ -101,7 +101,6 @@ CREATE TABLE test_vdx ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go index 9a4d7c50dbd..3280d64d433 100644 --- a/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go @@ -63,7 +63,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go index 915d76051a4..81bb6b90ee5 100644 --- a/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go @@ -64,7 +64,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go index 20d255941db..decf2f0dfdd 100644 --- a/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go @@ -40,7 +40,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go index d4a61665a6d..320cbc87172 100644 --- a/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go @@ -40,7 +40,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/reservedconn/sysvar_test.go b/go/test/endtoend/vtgate/reservedconn/sysvar_test.go index e7e0cfb0259..8bda7dea121 100644 --- a/go/test/endtoend/vtgate/reservedconn/sysvar_test.go +++ b/go/test/endtoend/vtgate/reservedconn/sysvar_test.go @@ -29,11 +29,9 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" ) func TestSetSysVarSingle(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() type queriesWithExpectations struct { name, expr string diff --git a/go/test/endtoend/vtgate/reservedconn/udv_test.go b/go/test/endtoend/vtgate/reservedconn/udv_test.go index 55f4c54c612..14b65dbcd35 100644 --- a/go/test/endtoend/vtgate/reservedconn/udv_test.go +++ b/go/test/endtoend/vtgate/reservedconn/udv_test.go @@ -31,11 +31,9 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" ) func TestSetUDV(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() type queriesWithExpectations struct { @@ -123,7 +121,6 @@ func TestSetUDV(t *testing.T) { } func TestMysqlDumpInitialLog(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) diff --git a/go/test/endtoend/vtgate/schema/schema_test.go b/go/test/endtoend/vtgate/schema/schema_test.go index 6b2e8ef7e61..fd84b5b2793 100644 --- a/go/test/endtoend/vtgate/schema/schema_test.go +++ b/go/test/endtoend/vtgate/schema/schema_test.go @@ -55,7 +55,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -101,7 +100,6 @@ func TestMain(m *testing.M) { } func TestSchemaChange(t *testing.T) { - defer cluster.PanicHandler(t) testWithInitialSchema(t) testWithAlterSchema(t) testWithAlterDatabase(t) @@ -296,7 +294,7 @@ func testCopySchemaShards(t *testing.T, source string, shard int) { checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[1], 0) // Run the command twice to make sure it's idempotent. for i := 0; i < 2; i++ { - err := clusterInstance.VtctlclientProcess.ExecuteCommand("CopySchemaShard", source, fmt.Sprintf("%s/%d", keyspaceName, shard)) + err := clusterInstance.VtctldClientProcess.ExecuteCommand("CopySchemaShard", source, fmt.Sprintf("%s/%d", keyspaceName, shard)) require.Nil(t, err) } // shard2 primary should look the same as the replica we copied from @@ -331,7 +329,7 @@ func testCopySchemaShardWithDifferentDB(t *testing.T, shard int) { err = clusterInstance.VtctldClientProcess.ExecuteCommand("ExecuteFetchAsDBA", "--json", tabletAlias, "ALTER DATABASE vt_ks CHARACTER SET latin1") require.Nil(t, err) - output, err := clusterInstance.VtctlclientProcess.ExecuteCommandWithOutput("CopySchemaShard", source, fmt.Sprintf("%s/%d", keyspaceName, shard)) + output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("CopySchemaShard", source, fmt.Sprintf("%s/%d", keyspaceName, shard)) require.Error(t, err) assert.True(t, strings.Contains(output, "schemas are different")) diff --git a/go/test/endtoend/vtgate/schematracker/loadkeyspace/schema_load_keyspace_test.go b/go/test/endtoend/vtgate/schematracker/loadkeyspace/schema_load_keyspace_test.go index 9586206221e..ec201487887 100644 --- a/go/test/endtoend/vtgate/schematracker/loadkeyspace/schema_load_keyspace_test.go +++ b/go/test/endtoend/vtgate/schematracker/loadkeyspace/schema_load_keyspace_test.go @@ -57,7 +57,6 @@ var ( ) func TestLoadKeyspaceWithNoTablet(t *testing.T) { - defer cluster.PanicHandler(t) var err error clusterInstance = cluster.NewCluster(cell, hostname) @@ -100,7 +99,6 @@ func TestLoadKeyspaceWithNoTablet(t *testing.T) { } func TestNoInitialKeyspace(t *testing.T) { - defer cluster.PanicHandler(t) var err error clusterInstance = cluster.NewCluster(cell, hostname) diff --git a/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go b/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go index 3bb4f6dfd9f..1943fefa9d7 100644 --- a/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go +++ b/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go @@ -64,7 +64,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode := func() int { @@ -116,7 +115,6 @@ func TestMain(m *testing.M) { } func TestVSchemaTrackerInit(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -137,7 +135,6 @@ func TestVSchemaTrackerInit(t *testing.T) { // properly handles primary tablet restarts -- meaning that we maintain // the exact same vschema state as before the restart. func TestVSchemaTrackerKeyspaceReInit(t *testing.T) { - defer cluster.PanicHandler(t) primaryTablet := clusterInstance.Keyspaces[0].Shards[0].PrimaryTablet() diff --git a/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go b/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go index 50042f3142a..5f82bd5d71a 100644 --- a/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go +++ b/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go @@ -48,7 +48,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -161,7 +160,6 @@ func TestNewTable(t *testing.T) { } func TestAmbiguousColumnJoin(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) diff --git a/go/test/endtoend/vtgate/schematracker/sharded_prs/st_sharded_test.go b/go/test/endtoend/vtgate/schematracker/sharded_prs/st_sharded_test.go index 09bd97eb9fe..6fbd3f3d33c 100644 --- a/go/test/endtoend/vtgate/schematracker/sharded_prs/st_sharded_test.go +++ b/go/test/endtoend/vtgate/schematracker/sharded_prs/st_sharded_test.go @@ -122,7 +122,6 @@ create table t8( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -208,7 +207,6 @@ func TestMain(m *testing.M) { } func TestAddColumn(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) diff --git a/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go b/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go index 5ecf89a5db7..4256727915d 100644 --- a/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go +++ b/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go @@ -49,7 +49,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -112,7 +111,6 @@ func TestMain(m *testing.M) { } func TestNewUnshardedTable(t *testing.T) { - defer cluster.PanicHandler(t) // create a sql connection ctx := context.Background() @@ -182,7 +180,6 @@ func TestNewUnshardedTable(t *testing.T) { // creating two tables having the same name differing only in casing, but other operating systems don't. // More information at https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html#:~:text=Table%20names%20are%20stored%20in,lowercase%20on%20storage%20and%20lookup. func TestCaseSensitiveSchemaTracking(t *testing.T) { - defer cluster.PanicHandler(t) // create a sql connection ctx := context.Background() diff --git a/go/test/endtoend/vtgate/sec_vind/main_test.go b/go/test/endtoend/vtgate/sec_vind/main_test.go index 7aa5df76a83..7ec0d5c0682 100644 --- a/go/test/endtoend/vtgate/sec_vind/main_test.go +++ b/go/test/endtoend/vtgate/sec_vind/main_test.go @@ -44,7 +44,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -101,7 +100,6 @@ func start(t *testing.T) (*mysql.Conn, func()) { return conn, func() { deleteAll() conn.Close() - cluster.PanicHandler(t) } } diff --git a/go/test/endtoend/vtgate/sequence/seq_test.go b/go/test/endtoend/vtgate/sequence/seq_test.go index 1bda37094b2..0fc1c810eb3 100644 --- a/go/test/endtoend/vtgate/sequence/seq_test.go +++ b/go/test/endtoend/vtgate/sequence/seq_test.go @@ -174,7 +174,6 @@ CREATE TABLE allDefaults ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -216,7 +215,6 @@ func TestMain(m *testing.M) { } func TestSeq(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -274,7 +272,6 @@ func TestSeq(t *testing.T) { } func TestDotTableSeq(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -297,7 +294,6 @@ func TestDotTableSeq(t *testing.T) { } func TestInsertAllDefaults(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", diff --git a/go/test/endtoend/vtgate/tablet_healthcheck/reparent_test.go b/go/test/endtoend/vtgate/tablet_healthcheck/reparent_test.go index d6357ce8f2a..77e9a58cf69 100644 --- a/go/test/endtoend/vtgate/tablet_healthcheck/reparent_test.go +++ b/go/test/endtoend/vtgate/tablet_healthcheck/reparent_test.go @@ -89,7 +89,6 @@ create table corder( // TestMain sets up the vitess cluster for any subsequent tests func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/tablet_healthcheck_cache/correctness_test.go b/go/test/endtoend/vtgate/tablet_healthcheck_cache/correctness_test.go index 50529d9fdf9..3457a2cab3c 100644 --- a/go/test/endtoend/vtgate/tablet_healthcheck_cache/correctness_test.go +++ b/go/test/endtoend/vtgate/tablet_healthcheck_cache/correctness_test.go @@ -86,7 +86,6 @@ create table corder( // TestMain sets up the vitess cluster for any subsequent tests func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { diff --git a/go/test/endtoend/vtgate/unsharded/main_test.go b/go/test/endtoend/vtgate/unsharded/main_test.go index e1818735ed1..307bb7fcf23 100644 --- a/go/test/endtoend/vtgate/unsharded/main_test.go +++ b/go/test/endtoend/vtgate/unsharded/main_test.go @@ -147,7 +147,6 @@ END; ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -192,7 +191,6 @@ func TestMain(m *testing.M) { func TestSelectIntoAndLoadFrom(t *testing.T) { // Test is skipped because it requires secure-file-priv variable to be set to not NULL or empty. t.Skip() - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -227,7 +225,6 @@ func TestSelectIntoAndLoadFrom(t *testing.T) { } func TestEmptyStatement(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -244,7 +241,6 @@ func TestEmptyStatement(t *testing.T) { } func TestTopoDownServingQuery(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -264,7 +260,6 @@ func TestTopoDownServingQuery(t *testing.T) { } func TestInsertAllDefaults(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -279,7 +274,6 @@ func TestInsertAllDefaults(t *testing.T) { } func TestDDLUnsharded(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -300,7 +294,6 @@ func TestDDLUnsharded(t *testing.T) { } func TestCallProcedure(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -347,7 +340,6 @@ func TestCallProcedure(t *testing.T) { } func TestTempTable(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -372,7 +364,6 @@ func TestTempTable(t *testing.T) { } func TestReservedConnDML(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", @@ -395,7 +386,6 @@ func TestReservedConnDML(t *testing.T) { } func TestNumericPrecisionScale(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ Host: "localhost", diff --git a/go/test/endtoend/vtgate/vindex_bindvars/main_test.go b/go/test/endtoend/vtgate/vindex_bindvars/main_test.go index 3251668e155..84c2c825784 100644 --- a/go/test/endtoend/vtgate/vindex_bindvars/main_test.go +++ b/go/test/endtoend/vtgate/vindex_bindvars/main_test.go @@ -265,7 +265,6 @@ CREATE TABLE thex ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitCode := func() int { @@ -304,7 +303,6 @@ func TestMain(m *testing.M) { } func TestVindexHexTypes(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.Nil(t, err) @@ -326,7 +324,6 @@ func TestVindexHexTypes(t *testing.T) { } func TestVindexBindVarOverlap(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.Nil(t, err) diff --git a/go/test/endtoend/vtgate/vschema/vschema_test.go b/go/test/endtoend/vtgate/vschema/vschema_test.go index eec54f8f47f..a3fea766584 100644 --- a/go/test/endtoend/vtgate/vschema/vschema_test.go +++ b/go/test/endtoend/vtgate/vschema/vschema_test.go @@ -18,21 +18,30 @@ package vschema import ( "context" + "encoding/json" "flag" "fmt" "os" + "path" + "strings" + "sync" + "sync/atomic" "testing" + "time" - "vitess.io/vitess/go/test/endtoend/utils" - + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/exp/rand" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/vtgate" ) var ( clusterInstance *cluster.LocalProcessCluster + configFile string vtParams mysql.ConnParams hostname = "localhost" keyspaceName = "ks" @@ -53,7 +62,6 @@ var ( ) func TestMain(m *testing.M) { - defer cluster.PanicHandler(nil) flag.Parse() exitcode, err := func() (int, error) { @@ -66,7 +74,21 @@ func TestMain(m *testing.M) { } // List of users authorized to execute vschema ddl operations - clusterInstance.VtGateExtraArgs = []string{"--vschema_ddl_authorized_users=%", "--schema_change_signal=false"} + if utils.BinaryIsAtLeastAtVersion(22, "vtgate") { + timeNow := time.Now().Unix() + configFile = path.Join(os.TempDir(), fmt.Sprintf("vtgate-config-%d.json", timeNow)) + err := writeConfig(configFile, map[string]string{ + "vschema_ddl_authorized_users": "%", + }) + if err != nil { + return 1, err + } + defer os.Remove(configFile) + + clusterInstance.VtGateExtraArgs = []string{fmt.Sprintf("--config-file=%s", configFile), "--schema_change_signal=false"} + } else { + clusterInstance.VtGateExtraArgs = []string{"--vschema_ddl_authorized_users=%", "--schema_change_signal=false"} + } // Start keyspace keyspace := &cluster.Keyspace{ @@ -96,8 +118,16 @@ func TestMain(m *testing.M) { } +func writeConfig(path string, cfg map[string]string) error { + file, err := os.Create(path) + if err != nil { + return err + } + defer file.Close() + return json.NewEncoder(file).Encode(cfg) +} + func TestVSchema(t *testing.T) { - defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -138,4 +168,89 @@ func TestVSchema(t *testing.T) { utils.AssertMatches(t, conn, "delete from vt_user", `[]`) + if utils.BinaryIsAtLeastAtVersion(22, "vtgate") { + // Don't allow any users to modify the vschema via the SQL API + // in order to test that behavior. + writeConfig(configFile, map[string]string{ + "vschema_ddl_authorized_users": "", + }) + // Allow anyone to modify the vschema via the SQL API again when + // the test completes. + defer func() { + writeConfig(configFile, map[string]string{ + "vschema_ddl_authorized_users": "%", + }) + }() + require.EventuallyWithT(t, func(t *assert.CollectT) { + _, err = conn.ExecuteFetch("ALTER VSCHEMA DROP TABLE main", 1000, false) + assert.Error(t, err) + assert.ErrorContains(t, err, "is not authorized to perform vschema operations") + }, 5*time.Second, 100*time.Millisecond) + } +} + +// TestVSchemaSQLAPIConcurrency tests that we prevent lost writes when we have +// concurrent vschema changes being made via the SQL API. +func TestVSchemaSQLAPIConcurrency(t *testing.T) { + if !utils.BinaryIsAtLeastAtVersion(22, "vtgate") { + t.Skip("This test requires vtgate version 22 or higher") + } + + ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second) + defer cancel() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + initialVSchema, err := conn.ExecuteFetch("SHOW VSCHEMA TABLES", -1, false) + require.NoError(t, err) + baseTableName := "t" + numTables := 1000 + mysqlConns := make([]*mysql.Conn, numTables) + for i := 0; i < numTables; i++ { + c, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + mysqlConns[i] = c + defer c.Close() + } + + isVersionMismatchErr := func(err error) bool { + // The error we get is an SQL error so we have to do string matching. + return err != nil && strings.Contains(err.Error(), vtgate.ErrStaleVSchema.Error()) + } + + wg := sync.WaitGroup{} + preventedLostWrites := atomic.Bool{} + for i := 0; i < numTables; i++ { + wg.Add(1) + go func() { + defer wg.Done() + time.Sleep(time.Duration(rand.Intn(100) * int(time.Nanosecond))) + tableName := fmt.Sprintf("%s%d", baseTableName, i) + _, err = mysqlConns[i].ExecuteFetch(fmt.Sprintf("ALTER VSCHEMA ADD TABLE %s", tableName), -1, false) + if isVersionMismatchErr(err) { + preventedLostWrites.Store(true) + } else { + require.NoError(t, err) + time.Sleep(time.Duration(rand.Intn(75) * int(time.Nanosecond))) + _, err = mysqlConns[i].ExecuteFetch(fmt.Sprintf("ALTER VSCHEMA DROP TABLE %s", tableName), -1, false) + if isVersionMismatchErr(err) { + preventedLostWrites.Store(true) + } else { + require.NoError(t, err) + } + } + }() + } + wg.Wait() + require.True(t, preventedLostWrites.Load()) + + // Cleanup any tables that were not dropped because the DROP query + // failed due to a bad node version. + for i := 0; i < numTables; i++ { + tableName := fmt.Sprintf("%s%d", baseTableName, i) + _, _ = mysqlConns[i].ExecuteFetch(fmt.Sprintf("ALTER VSCHEMA DROP TABLE %s", tableName), -1, false) + } + // Confirm that we're back to the initial state. + utils.AssertMatches(t, conn, "SHOW VSCHEMA TABLES", fmt.Sprintf("%v", initialVSchema.Rows)) } diff --git a/go/test/endtoend/vtorc/api/api_test.go b/go/test/endtoend/vtorc/api/api_test.go index 638ea5fa72e..22091e5cce5 100644 --- a/go/test/endtoend/vtorc/api/api_test.go +++ b/go/test/endtoend/vtorc/api/api_test.go @@ -33,7 +33,6 @@ import ( // TestAPIEndpoints tests the various API endpoints that VTOrc offers. func TestAPIEndpoints(t *testing.T) { - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -140,7 +139,7 @@ func TestAPIEndpoints(t *testing.T) { }) t.Run("Replication Analysis API", func(t *testing.T) { - // use vtctlclient to stop replication + // use vtctldclient to stop replication _, err := clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("StopReplication", replica.Alias) require.NoError(t, err) diff --git a/go/test/endtoend/vtorc/api/config_test.go b/go/test/endtoend/vtorc/api/config_test.go index 71cc6291be7..821b0f8071e 100644 --- a/go/test/endtoend/vtorc/api/config_test.go +++ b/go/test/endtoend/vtorc/api/config_test.go @@ -30,7 +30,6 @@ import ( // TestDynamicConfigs tests the dyanamic configurations that VTOrc offers. func TestDynamicConfigs(t *testing.T) { - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{}, 1, "") vtorc := clusterInfo.ClusterInstance.VTOrcProcesses[0] diff --git a/go/test/endtoend/vtorc/api/main_test.go b/go/test/endtoend/vtorc/api/main_test.go index f89326bc856..cc3e796b293 100644 --- a/go/test/endtoend/vtorc/api/main_test.go +++ b/go/test/endtoend/vtorc/api/main_test.go @@ -21,7 +21,6 @@ import ( "os" "testing" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/vtorc/utils" ) @@ -53,8 +52,6 @@ func TestMain(m *testing.M) { return m.Run(), nil }() - cluster.PanicHandler(nil) - if clusterInfo != nil { // stop vtorc first otherwise its logs get polluted // with instances being unreachable triggering unnecessary operations diff --git a/go/test/endtoend/vtorc/general/main_test.go b/go/test/endtoend/vtorc/general/main_test.go index 6db0792de3a..0cd88cd378c 100644 --- a/go/test/endtoend/vtorc/general/main_test.go +++ b/go/test/endtoend/vtorc/general/main_test.go @@ -21,7 +21,6 @@ import ( "os" "testing" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/vtorc/utils" ) @@ -47,8 +46,6 @@ func TestMain(m *testing.M) { return m.Run(), nil }() - cluster.PanicHandler(nil) - if clusterInfo != nil { // stop vtorc first otherwise its logs get polluted // with instances being unreachable triggering unnecessary operations diff --git a/go/test/endtoend/vtorc/general/vtorc_test.go b/go/test/endtoend/vtorc/general/vtorc_test.go index 9cc931897bf..4a2f50b4168 100644 --- a/go/test/endtoend/vtorc/general/vtorc_test.go +++ b/go/test/endtoend/vtorc/general/vtorc_test.go @@ -40,7 +40,6 @@ import ( // verify that with multiple vtorc instances, we still only have 1 PlannedReparentShard call func TestPrimaryElection(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 2, "") @@ -66,7 +65,6 @@ func TestPrimaryElection(t *testing.T) { // if it has an errant GTID. func TestErrantGTIDOnPreviousPrimary(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 3, 0, []string{"--change-tablets-with-errant-gtid-to-drained"}, cluster.VTOrcConfiguration{}, 1, "") keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] shard0 := &keyspace.Shards[0] @@ -126,7 +124,6 @@ func TestErrantGTIDOnPreviousPrimary(t *testing.T) { // verify replication is setup func TestSingleKeyspace(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 1, 1, []string{"--clusters_to_watch", "ks"}, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -145,7 +142,6 @@ func TestSingleKeyspace(t *testing.T) { // verify replication is setup func TestKeyspaceShard(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 1, 1, []string{"--clusters_to_watch", "ks/0"}, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -167,7 +163,6 @@ func TestKeyspaceShard(t *testing.T) { // 6. disable recoveries and make sure the detected problems are set correctly. func TestVTOrcRepairs(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 3, 0, []string{"--change-tablets-with-errant-gtid-to-drained"}, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -221,7 +216,7 @@ func TestVTOrcRepairs(t *testing.T) { }) t.Run("StopReplication", func(t *testing.T) { - // use vtctlclient to stop replication + // use vtctldclient to stop replication _, err := clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("StopReplication", replica.Alias) require.NoError(t, err) @@ -346,7 +341,6 @@ func TestRepairAfterTER(t *testing.T) { // test fails intermittently on CI, skip until it can be fixed. t.SkipNow() defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 0, nil, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -480,7 +474,6 @@ func TestSemiSync(t *testing.T) { // TestVTOrcWithPrs tests that VTOrc works fine even when PRS is called from vtctld func TestVTOrcWithPrs(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 4, 0, nil, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -530,7 +523,6 @@ func TestVTOrcWithPrs(t *testing.T) { // TestMultipleDurabilities tests that VTOrc works with 2 keyspaces having 2 different durability policies func TestMultipleDurabilities(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) // Setup a normal cluster and start vtorc utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 1, 1, nil, cluster.VTOrcConfiguration{}, 1, "") // Setup a semi-sync cluster @@ -551,7 +543,6 @@ func TestMultipleDurabilities(t *testing.T) { // TestDrainedTablet tests that we don't forget drained tablets and they still show up in the vtorc output. func TestDrainedTablet(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) // Setup a normal cluster and start vtorc utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 0, nil, cluster.VTOrcConfiguration{}, 1, "") @@ -639,7 +630,6 @@ func TestDurabilityPolicySetLater(t *testing.T) { func TestFullStatusConnectionPooling(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 4, 0, []string{ "--tablet_manager_grpc_concurrency=1", }, cluster.VTOrcConfiguration{ diff --git a/go/test/endtoend/vtorc/primaryfailure/main_test.go b/go/test/endtoend/vtorc/primaryfailure/main_test.go index a3e50bd0cc9..cd03df01bd6 100644 --- a/go/test/endtoend/vtorc/primaryfailure/main_test.go +++ b/go/test/endtoend/vtorc/primaryfailure/main_test.go @@ -21,7 +21,6 @@ import ( "os" "testing" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/vtorc/utils" ) @@ -53,8 +52,6 @@ func TestMain(m *testing.M) { return m.Run(), nil }() - cluster.PanicHandler(nil) - if clusterInfo != nil { // stop vtorc first otherwise its logs get polluted // with instances being unreachable triggering unnecessary operations diff --git a/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go b/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go index a46e3789730..de60420eee3 100644 --- a/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go +++ b/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/vtorc/utils" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/logic" ) @@ -39,13 +40,12 @@ import ( // Also tests that VTOrc can handle multiple failures, if the durability policies allow it func TestDownPrimary(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) // We specify the --wait-replicas-timeout to a small value because we spawn a cross-cell replica later in the test. // If that replica is more advanced than the same-cell-replica, then we try to promote the cross-cell replica as an intermediate source. // If we don't specify a small value of --wait-replicas-timeout, then we would end up waiting for 30 seconds for the dead-primary to respond, failing this test. utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, []string{"--remote_operation_timeout=10s", "--wait-replicas-timeout=5s"}, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, - }, 1, "semi_sync") + }, 1, policy.DurabilitySemiSync) keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] shard0 := &keyspace.Shards[0] // find primary from topo @@ -116,8 +116,7 @@ func TestDownPrimary(t *testing.T) { // bring down primary before VTOrc has started, let vtorc repair. func TestDownPrimaryBeforeVTOrc(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) - utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{}, 0, "none") + utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{}, 0, policy.DurabilityNone) keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] shard0 := &keyspace.Shards[0] curPrimary := shard0.Vttablets[0] @@ -172,8 +171,7 @@ func TestDownPrimaryBeforeVTOrc(t *testing.T) { // delete the primary record and let vtorc repair. func TestDeletedPrimaryTablet(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) - utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, []string{"--remote_operation_timeout=10s"}, cluster.VTOrcConfiguration{}, 1, "none") + utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, []string{"--remote_operation_timeout=10s"}, cluster.VTOrcConfiguration{}, 1, policy.DurabilityNone) keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] shard0 := &keyspace.Shards[0] // find primary from topo @@ -202,7 +200,7 @@ func TestDeletedPrimaryTablet(t *testing.T) { // Disable VTOrc recoveries vtOrcProcess.DisableGlobalRecoveries(t) - // use vtctlclient to stop replication on the replica + // use vtctldclient to stop replication on the replica _, err := clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("StopReplication", replica.Alias) require.NoError(t, err) // insert a write that is not available on the replica. @@ -212,7 +210,7 @@ func TestDeletedPrimaryTablet(t *testing.T) { _ = curPrimary.VttabletProcess.TearDown() err = curPrimary.MysqlctlProcess.Stop() require.NoError(t, err) - // use vtctlclient to start replication on the replica back + // use vtctldclient to start replication on the replica back _, err = clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("StartReplication", replica.Alias) require.NoError(t, err) err = clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommand("DeleteTablets", "--allow-primary", curPrimary.Alias) @@ -239,13 +237,12 @@ func TestDeletedPrimaryTablet(t *testing.T) { // that primary is unreachable. This help us save few seconds depending on value of `RemoteOperationTimeout` flag. func TestDeadPrimaryRecoversImmediately(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) // We specify the --wait-replicas-timeout to a small value because we spawn a cross-cell replica later in the test. // If that replica is more advanced than the same-cell-replica, then we try to promote the cross-cell replica as an intermediate source. // If we don't specify a small value of --wait-replicas-timeout, then we would end up waiting for 30 seconds for the dead-primary to respond, failing this test. utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, []string{"--remote_operation_timeout=10s", "--wait-replicas-timeout=5s"}, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, - }, 1, "semi_sync") + }, 1, policy.DurabilitySemiSync) keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] shard0 := &keyspace.Shards[0] // find primary from topo @@ -322,7 +319,6 @@ func TestDeadPrimaryRecoversImmediately(t *testing.T) { // covers part of the test case master-failover-lost-replicas from orchestrator func TestCrossDataCenterFailure(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -368,7 +364,6 @@ func TestCrossDataCenterFailure(t *testing.T) { // In case of no viable candidates, we should error out func TestCrossDataCenterFailureError(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 1, 1, nil, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -415,7 +410,6 @@ func TestLostRdonlyOnPrimaryFailure(t *testing.T) { // were detected by vtorc and could be configured to have their sources detached t.Skip() defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 2, nil, cluster.VTOrcConfiguration{ PreventCrossCellFailover: true, }, 1, "") @@ -495,7 +489,6 @@ func TestLostRdonlyOnPrimaryFailure(t *testing.T) { // covers the test case master-failover-fail-promotion-lag-minutes-success from orchestrator func TestPromotionLagSuccess(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{ ReplicationLagQuery: "select 59", FailPrimaryPromotionOnLagMinutes: 1, @@ -545,7 +538,6 @@ func TestPromotionLagFailure(t *testing.T) { // was smaller than the configured value, otherwise it would fail the promotion t.Skip() defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 3, 1, nil, cluster.VTOrcConfiguration{ ReplicationLagQuery: "select 61", FailPrimaryPromotionOnLagMinutes: 1, @@ -598,7 +590,6 @@ func TestPromotionLagFailure(t *testing.T) { // That is the replica which should be promoted in case of primary failure func TestDownPrimaryPromotionRule(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{ LockShardTimeoutSeconds: 5, }, 1, "test") @@ -646,7 +637,6 @@ func TestDownPrimaryPromotionRule(t *testing.T) { // It should also be caught up when it is promoted func TestDownPrimaryPromotionRuleWithLag(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{ LockShardTimeoutSeconds: 5, }, 1, "test") @@ -726,7 +716,6 @@ func TestDownPrimaryPromotionRuleWithLag(t *testing.T) { // It should also be caught up when it is promoted func TestDownPrimaryPromotionRuleWithLagCrossCenter(t *testing.T) { defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) - defer cluster.PanicHandler(t) utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 1, nil, cluster.VTOrcConfiguration{ LockShardTimeoutSeconds: 5, PreventCrossCellFailover: true, diff --git a/go/test/endtoend/vtorc/readtopologyinstance/main_test.go b/go/test/endtoend/vtorc/readtopologyinstance/main_test.go index 823655ed785..6a565ac046f 100644 --- a/go/test/endtoend/vtorc/readtopologyinstance/main_test.go +++ b/go/test/endtoend/vtorc/readtopologyinstance/main_test.go @@ -50,9 +50,9 @@ func TestReadTopologyInstanceBufferable(t *testing.T) { // Change the args such that they match how we would invoke VTOrc os.Args = []string{"vtorc", - "--topo_global_server_address", clusterInfo.ClusterInstance.VtctlProcess.TopoGlobalAddress, - "--topo_implementation", clusterInfo.ClusterInstance.VtctlProcess.TopoImplementation, - "--topo_global_root", clusterInfo.ClusterInstance.VtctlProcess.TopoGlobalRoot, + "--topo_global_server_address", clusterInfo.ClusterInstance.VtctldClientProcess.TopoGlobalAddress, + "--topo_implementation", clusterInfo.ClusterInstance.VtctldClientProcess.TopoImplementation, + "--topo_global_root", clusterInfo.ClusterInstance.VtctldClientProcess.TopoGlobalRoot, } servenv.ParseFlags("vtorc") config.SetInstancePollTime(1 * time.Second) @@ -86,7 +86,7 @@ func TestReadTopologyInstanceBufferable(t *testing.T) { assert.Equal(t, "ON", primaryInstance.GTIDMode) assert.Equal(t, "FULL", primaryInstance.BinlogRowImage) assert.Contains(t, primaryInstance.SelfBinlogCoordinates.LogFile, fmt.Sprintf("vt-0000000%d-bin", primary.TabletUID)) - assert.Greater(t, primaryInstance.SelfBinlogCoordinates.LogPos, uint32(0)) + assert.Greater(t, primaryInstance.SelfBinlogCoordinates.LogPos, uint64(0)) assert.True(t, primaryInstance.SemiSyncPrimaryEnabled) assert.True(t, primaryInstance.SemiSyncReplicaEnabled) assert.True(t, primaryInstance.SemiSyncPrimaryStatus) @@ -138,7 +138,7 @@ func TestReadTopologyInstanceBufferable(t *testing.T) { assert.Equal(t, utils.Hostname, replicaInstance.SourceHost) assert.Equal(t, primary.MySQLPort, replicaInstance.SourcePort) assert.Contains(t, replicaInstance.SelfBinlogCoordinates.LogFile, fmt.Sprintf("vt-0000000%d-bin", replica.TabletUID)) - assert.Greater(t, replicaInstance.SelfBinlogCoordinates.LogPos, uint32(0)) + assert.Greater(t, replicaInstance.SelfBinlogCoordinates.LogPos, uint64(0)) assert.False(t, replicaInstance.SemiSyncPrimaryEnabled) assert.True(t, replicaInstance.SemiSyncReplicaEnabled) assert.False(t, replicaInstance.SemiSyncPrimaryStatus) @@ -156,16 +156,15 @@ func TestReadTopologyInstanceBufferable(t *testing.T) { assert.True(t, replicaInstance.ReplicationIOThreadRuning) assert.True(t, replicaInstance.ReplicationSQLThreadRuning) assert.Equal(t, replicaInstance.ReadBinlogCoordinates.LogFile, primaryInstance.SelfBinlogCoordinates.LogFile) - assert.Greater(t, replicaInstance.ReadBinlogCoordinates.LogPos, uint32(0)) + assert.Greater(t, replicaInstance.ReadBinlogCoordinates.LogPos, uint64(0)) assert.Equal(t, replicaInstance.ExecBinlogCoordinates.LogFile, primaryInstance.SelfBinlogCoordinates.LogFile) - assert.Greater(t, replicaInstance.ExecBinlogCoordinates.LogPos, uint32(0)) + assert.Greater(t, replicaInstance.ExecBinlogCoordinates.LogPos, uint64(0)) assert.Contains(t, replicaInstance.RelaylogCoordinates.LogFile, fmt.Sprintf("vt-0000000%d-relay", replica.TabletUID)) - assert.Greater(t, replicaInstance.RelaylogCoordinates.LogPos, uint32(0)) + assert.Greater(t, replicaInstance.RelaylogCoordinates.LogPos, uint64(0)) assert.Empty(t, replicaInstance.LastIOError) assert.Empty(t, replicaInstance.LastSQLError) assert.EqualValues(t, 0, replicaInstance.SQLDelay) assert.True(t, replicaInstance.UsingOracleGTID) - assert.False(t, replicaInstance.UsingMariaDBGTID) assert.Equal(t, replicaInstance.SourceUUID, primaryInstance.ServerUUID) assert.False(t, replicaInstance.HasReplicationFilters) assert.LessOrEqual(t, int(replicaInstance.SecondsBehindPrimary.Int64), 1) diff --git a/go/test/endtoend/vtorc/utils/utils.go b/go/test/endtoend/vtorc/utils/utils.go index 456d55518dd..b00e3897a61 100644 --- a/go/test/endtoend/vtorc/utils/utils.go +++ b/go/test/endtoend/vtorc/utils/utils.go @@ -40,6 +40,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" // Register topo implementations. _ "vitess.io/vitess/go/vt/topo/consultopo" @@ -89,7 +90,7 @@ func CreateClusterAndStartTopo(cellInfos []*CellInfo) (*VTOrcClusterInfo, error) if err != nil { return nil, err } - err = clusterInstance.VtctlProcess.AddCellInfo(Cell2) + err = clusterInstance.VtctldClientProcess.AddCellInfo(Cell2) if err != nil { return nil, err } @@ -101,7 +102,7 @@ func CreateClusterAndStartTopo(cellInfos []*CellInfo) (*VTOrcClusterInfo, error) } // create topo server connection - ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) return &VTOrcClusterInfo{ ClusterInstance: clusterInstance, Ts: ts, @@ -299,7 +300,7 @@ func SetupVttabletsAndVTOrcs(t *testing.T, clusterInfo *VTOrcClusterInfo, numRep } if durability == "" { - durability = "none" + durability = policy.DurabilityNone } out, err := clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, fmt.Sprintf("--durability-policy=%s", durability)) require.NoError(t, err, out) @@ -855,7 +856,7 @@ func SetupNewClusterSemiSync(t *testing.T) *VTOrcClusterInfo { require.NoError(t, err, out) // create topo server connection - ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctldClientProcess.TopoGlobalAddress, clusterInstance.VtctldClientProcess.TopoGlobalRoot) require.NoError(t, err) clusterInfo := &VTOrcClusterInfo{ ClusterInstance: clusterInstance, @@ -926,7 +927,7 @@ func AddSemiSyncKeyspace(t *testing.T, clusterInfo *VTOrcClusterInfo) { require.NoError(t, err) } - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInfo.ClusterInstance.VtctldProcess.GrpcPort, clusterInfo.ClusterInstance.TmpDirectory) + vtctldClientProcess := cluster.VtctldClientProcessInstance(clusterInfo.ClusterInstance.VtctldProcess.GrpcPort, clusterInfo.ClusterInstance.TopoPort, "localhost", clusterInfo.ClusterInstance.TmpDirectory) out, err := vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceSemiSyncName, "--durability-policy=semi_sync") require.NoError(t, err, out) } diff --git a/go/test/fuzzing/oss_fuzz_build.sh b/go/test/fuzzing/oss_fuzz_build.sh index 2cb991c4215..cde31291af1 100755 --- a/go/test/fuzzing/oss_fuzz_build.sh +++ b/go/test/fuzzing/oss_fuzz_build.sh @@ -54,10 +54,10 @@ mv api_marshal_fuzzer.go $SRC/vitess/go/test/fuzzing/ compile_go_fuzzer vitess.io/vitess/go/test/fuzzing FuzzAPIMarshal api_marshal_fuzzer # collation fuzzer -mv ./go/mysql/collations/uca_test.go \ - ./go/mysql/collations/uca_test_fuzz.go +mv ./go/mysql/collations/colldata/uca_test.go \ + ./go/mysql/collations/colldata/uca_test_fuzz.go -compile_go_fuzzer vitess.io/vitess/go/mysql/collations FuzzCollations fuzz_collations +compile_go_fuzzer vitess.io/vitess/go/mysql/collations/colldata FuzzCollations fuzz_collations compile_go_fuzzer vitess.io/vitess/go/vt/vtgate/planbuilder FuzzTestBuilder fuzz_test_builder gofuzz diff --git a/go/test/utils/binlog.go b/go/test/utils/binlog.go index d3f686f1a8a..6e43dd511ad 100644 --- a/go/test/utils/binlog.go +++ b/go/test/utils/binlog.go @@ -17,8 +17,10 @@ limitations under the License. package utils import ( + "errors" "fmt" "os" + "strconv" "strings" ) @@ -27,9 +29,12 @@ const ( BinlogRowImageCnf = "binlog-row-image.cnf" ) -// SetBinlogRowImageMode creates a temp cnf file to set binlog_row_image to noblob for vreplication unit tests. -// It adds it to the EXTRA_MY_CNF environment variable which appends text from them into my.cnf. -func SetBinlogRowImageMode(mode string, cnfDir string) error { +// SetBinlogRowImageOptions creates a temp cnf file to set binlog_row_image=NOBLOB and +// optionally binlog_row_value_options=PARTIAL_JSON (since it does not exist in 5.7) +// for vreplication unit tests. +// It adds it to the EXTRA_MY_CNF environment variable which appends text from them +// into my.cnf. +func SetBinlogRowImageOptions(mode string, partialJSON bool, cnfDir string) error { var newCnfs []string // remove any existing extra cnfs for binlog row image @@ -55,6 +60,17 @@ func SetBinlogRowImageMode(mode string, cnfDir string) error { if err != nil { return err } + if partialJSON { + if !CIDBPlatformIsMySQL8orLater() { + return errors.New("partial JSON values are only supported in MySQL 8.0 or later") + } + // We're testing partial binlog row images so let's also test partial + // JSON values in the images. + _, err = f.WriteString("\nbinlog_row_value_options=PARTIAL_JSON\n") + if err != nil { + return err + } + } err = f.Close() if err != nil { return err @@ -68,3 +84,30 @@ func SetBinlogRowImageMode(mode string, cnfDir string) error { } return nil } + +// CIDBPlatformIsMySQL8orLater returns true if the CI_DB_PLATFORM environment +// variable is empty -- meaning we're not running in the CI and we assume +// MySQL8.0 or later is used, and you can understand the failures and make +// adjustments as necessary -- or it's set to reflect usage of MySQL 8.0 or +// later. This relies on the current standard values used such as mysql57, +// mysql80, mysql84, etc. This can be used when the CI test behavior needs +// to be altered based on the specific database platform we're testing against. +func CIDBPlatformIsMySQL8orLater() bool { + dbPlatform := strings.ToLower(os.Getenv("CI_DB_PLATFORM")) + if dbPlatform == "" { + // This is for local testing where we don't set the env var via + // the CI. + return true + } + if strings.HasPrefix(dbPlatform, "mysql") { + _, v, ok := strings.Cut(dbPlatform, "mysql") + if ok { + // We only want the major version. + version, err := strconv.Atoi(string(v[0])) + if err == nil && version >= 8 { + return true + } + } + } + return false +} diff --git a/go/test/utils/binlog_test.go b/go/test/utils/binlog_test.go index 593b964a171..d8a0d6d4222 100644 --- a/go/test/utils/binlog_test.go +++ b/go/test/utils/binlog_test.go @@ -24,19 +24,33 @@ import ( "github.com/stretchr/testify/require" ) -// TestSetBinlogRowImageMode tests the SetBinlogRowImageMode function. +// TestSetBinlogRowImageOptions tests the SetBinlogRowImageOptions function. func TestUtils(t *testing.T) { tmpDir := "/tmp" cnfFile := fmt.Sprintf("%s/%s", tmpDir, BinlogRowImageCnf) + // Test that setting the mode will create the cnf file and add it to the EXTRA_MY_CNF env var. - require.NoError(t, SetBinlogRowImageMode("noblob", tmpDir)) + require.NoError(t, SetBinlogRowImageOptions("noblob", false, tmpDir)) data, err := os.ReadFile(cnfFile) require.NoError(t, err) require.Contains(t, string(data), "binlog_row_image=noblob") require.Contains(t, os.Getenv(ExtraCnf), BinlogRowImageCnf) + // Test that setting the mode and passing true for includePartialJSON will set both options + // as expected. + if CIDBPlatformIsMySQL8orLater() { + require.NoError(t, SetBinlogRowImageOptions("noblob", true, tmpDir)) + data, err = os.ReadFile(cnfFile) + require.NoError(t, err) + require.Contains(t, string(data), "binlog_row_image=noblob") + require.Contains(t, string(data), "binlog_row_value_options=PARTIAL_JSON") + require.Contains(t, os.Getenv(ExtraCnf), BinlogRowImageCnf) + } else { + require.Error(t, SetBinlogRowImageOptions("noblob", true, tmpDir)) + } + // Test that clearing the mode will remove the cnf file and the cnf from the EXTRA_MY_CNF env var. - require.NoError(t, SetBinlogRowImageMode("", tmpDir)) + require.NoError(t, SetBinlogRowImageOptions("", false, tmpDir)) require.NotContains(t, os.Getenv(ExtraCnf), BinlogRowImageCnf) _, err = os.Stat(cnfFile) require.True(t, os.IsNotExist(err)) diff --git a/go/test/utils/diff.go b/go/test/utils/diff.go index 014d4760d87..2344c027c39 100644 --- a/go/test/utils/diff.go +++ b/go/test/utils/diff.go @@ -68,7 +68,7 @@ func MustMatchFn(ignoredFields ...string) func(t *testing.T, want, got any, errM t.Helper() diff := cmp.Diff(want, got, diffOpts...) if diff != "" { - t.Fatalf("%v: (-want +got)\n%v", errMsg, diff) + require.FailNow(t, "%v: (-want +got)\n%v", errMsg, diff) } } } diff --git a/go/test/vschemawrapper/vschema_wrapper.go b/go/test/vschemawrapper/vschema_wrapper.go index 3f9f072afc6..5b1c6b033e6 100644 --- a/go/test/vschemawrapper/vschema_wrapper.go +++ b/go/test/vschemawrapper/vschema_wrapper.go @@ -18,7 +18,9 @@ package vschemawrapper import ( "context" + "errors" "fmt" + "sort" "strings" "vitess.io/vitess/go/mysql/collations" @@ -263,7 +265,7 @@ func (vw *VSchemaWrapper) FindTable(tab sqlparser.TableName) (*vindexes.Table, s return table, destKeyspace, destTabletType, destTarget, nil } -func (vw *VSchemaWrapper) FindView(tab sqlparser.TableName) sqlparser.SelectStatement { +func (vw *VSchemaWrapper) FindView(tab sqlparser.TableName) sqlparser.TableStatement { destKeyspace, _, _, err := topoproto.ParseDestination(tab.Qualifier.String(), topodatapb.TabletType_PRIMARY) if err != nil { return nil @@ -271,19 +273,19 @@ func (vw *VSchemaWrapper) FindView(tab sqlparser.TableName) sqlparser.SelectStat return vw.V.FindView(destKeyspace, tab.Name.String()) } -func (vw *VSchemaWrapper) FindTableOrVindex(tab sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) { - return vw.Vcursor.FindTableOrVindex(tab) +func (vw *VSchemaWrapper) FindViewTarget(name sqlparser.TableName) (*vindexes.Keyspace, error) { + destKeyspace, _, _, err := topoproto.ParseDestination(name.Qualifier.String(), topodatapb.TabletType_PRIMARY) + if err != nil { + return nil, err + } + if ks, ok := vw.V.Keyspaces[destKeyspace]; ok { + return ks.Keyspace, nil + } + return nil, nil } -func (vw *VSchemaWrapper) getfirstKeyspace() (ks *vindexes.Keyspace) { - var f string - for name, schema := range vw.V.Keyspaces { - if f == "" || f > name { - f = name - ks = schema.Keyspace - } - } - return +func (vw *VSchemaWrapper) FindTableOrVindex(tab sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) { + return vw.Vcursor.FindTableOrVindex(tab) } func (vw *VSchemaWrapper) getActualKeyspace() string { @@ -301,15 +303,32 @@ func (vw *VSchemaWrapper) getActualKeyspace() string { } func (vw *VSchemaWrapper) SelectedKeyspace() (*vindexes.Keyspace, error) { - return vw.V.Keyspaces["main"].Keyspace, nil + return vw.AnyKeyspace() } func (vw *VSchemaWrapper) AnyKeyspace() (*vindexes.Keyspace, error) { - return vw.SelectedKeyspace() + ks, found := vw.V.Keyspaces["main"] + if found { + return ks.Keyspace, nil + } + + size := len(vw.V.Keyspaces) + if size == 0 { + return nil, errors.New("no keyspace found in vschema") + } + + // Find the first keyspace in the map alphabetically to get deterministic results + keys := make([]string, size) + for key := range vw.V.Keyspaces { + keys = append(keys, key) + } + sort.Strings(keys) + + return vw.V.Keyspaces[keys[0]].Keyspace, nil } func (vw *VSchemaWrapper) FirstSortedKeyspace() (*vindexes.Keyspace, error) { - return vw.V.Keyspaces["main"].Keyspace, nil + return vw.AnyKeyspace() } func (vw *VSchemaWrapper) TargetString() string { @@ -344,12 +363,12 @@ func (vw *VSchemaWrapper) IsViewsEnabled() bool { // FindMirrorRule finds the mirror rule for the requested keyspace, table // name, and the tablet type in the VSchema. -func (vs *VSchemaWrapper) FindMirrorRule(tab sqlparser.TableName) (*vindexes.MirrorRule, error) { +func (vw *VSchemaWrapper) FindMirrorRule(tab sqlparser.TableName) (*vindexes.MirrorRule, error) { destKeyspace, destTabletType, _, err := topoproto.ParseDestination(tab.Qualifier.String(), topodatapb.TabletType_PRIMARY) if err != nil { return nil, err } - mirrorRule, err := vs.V.FindMirrorRule(destKeyspace, tab.Name.String(), destTabletType) + mirrorRule, err := vw.V.FindMirrorRule(destKeyspace, tab.Name.String(), destTabletType) if err != nil { return nil, err } diff --git a/go/timer/randticker_test.go b/go/timer/randticker_test.go index 59bcd1d89ea..7acdbf3156a 100644 --- a/go/timer/randticker_test.go +++ b/go/timer/randticker_test.go @@ -43,21 +43,3 @@ func TestTick(t *testing.T) { t.Error("Channel was not closed") } } - -func TestTickSkip(t *testing.T) { - tkr := NewRandTicker(10*time.Millisecond, 1*time.Millisecond) - time.Sleep(35 * time.Millisecond) - end := <-tkr.C - diff := time.Since(end) - if diff < 20*time.Millisecond { - t.Errorf("diff: %v, want >20ms", diff) - } - - // This tick should be up-to-date - end = <-tkr.C - diff = time.Since(end) - if diff > 1*time.Millisecond { - t.Errorf("diff: %v, want <1ms", diff) - } - tkr.Stop() -} diff --git a/go/tools/go-upgrade/go-upgrade.go b/go/tools/go-upgrade/go-upgrade.go index 3ca5f4aeb8b..7b36fd14c02 100644 --- a/go/tools/go-upgrade/go-upgrade.go +++ b/go/tools/go-upgrade/go-upgrade.go @@ -343,8 +343,10 @@ func replaceGoVersionInCodebase(old, new *version.Version) error { "./build.env", "./docker/bootstrap/Dockerfile.common", "./docker/lite/Dockerfile", + "./docker/lite/Dockerfile.mysql84", "./docker/lite/Dockerfile.percona80", "./docker/vttestserver/Dockerfile.mysql80", + "./docker/vttestserver/Dockerfile.mysql84", } filesToChange, err := getListOfFilesInPaths(explore) if err != nil { diff --git a/go/tools/sizegen/sizegen.go b/go/tools/sizegen/sizegen.go index 7ecd50e3d8c..cc733c8826d 100644 --- a/go/tools/sizegen/sizegen.go +++ b/go/tools/sizegen/sizegen.go @@ -107,6 +107,8 @@ func isPod(tt types.Type) bool { return false } return true + case *types.Alias: + return isPod(types.Unalias(tt)) default: return false } @@ -152,8 +154,37 @@ func (sizegen *sizegen) generateType(pkg *types.Package, file *codeFile, named * sizegen.generateTyp(tt) } }) + + case *types.Slice: + impl, flag := sizegen.sizeImplForSlice(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) + case *types.Map: + impl, flag := sizegen.sizeImplForMap(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) + case *types.Basic: + impl, flag := sizegen.sizeImplForBasic(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) + case *types.Signature: + impl, flag := sizegen.sizeImplForSignature(named.Obj(), tt) + file.impls = append(file.impls, codeImpl{ + code: impl, + name: named.String(), + flags: flag, + }) default: - // no-op + panic(fmt.Sprintf("unhandled type: %v (%T)", named, tt)) } } @@ -163,6 +194,8 @@ func (sizegen *sizegen) generateTyp(tt types.Type) { sizegen.generateKnownType(tt) case *types.Alias: sizegen.generateTyp(types.Unalias(tt)) + default: + panic(fmt.Sprintf("unhandled type: %v (%T)", tt, tt)) } } @@ -284,6 +317,77 @@ func (sizegen *sizegen) sizeImplForStruct(name *types.TypeName, st *types.Struct return f, funcFlags } +func (sizegen *sizegen) sizeImplForSlice(name *types.TypeName, st *types.Slice) (jen.Code, codeFlag) { + var stmt []jen.Code + var funcFlags codeFlag + stmt, funcFlags = sizegen.sizeStmtForArray(stmt, jen.Op("*").Add(jen.Id("cached")), st.Elem()) + + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0))))) + b.Add(jen.Id("size").Op(":=").Lit(int64(0))) + b.Add(jen.If(jen.Id("alloc")).Block( + jen.Id("size").Op("+=").Lit(hack.RuntimeAllocSize(sizegen.sizes.Sizeof(st))), + )) + for _, s := range stmt { + b.Add(s) + } + b.Add(jen.Return(jen.Id("size"))) + }) + return f, funcFlags +} + +func (sizegen *sizegen) sizeImplForMap(name *types.TypeName, st *types.Map) (jen.Code, codeFlag) { + stmt := sizegen.sizeStmtForMap(jen.Op("*").Add(jen.Id("cached")), st) + + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0))))) + b.Add(jen.Id("size").Op(":=").Lit(int64(0))) + b.Add(jen.If(jen.Id("alloc")).Block( + jen.Id("size").Op("+=").Lit(hack.RuntimeAllocSize(sizegen.sizes.Sizeof(st))), + )) + for _, s := range stmt { + b.Add(s) + } + b.Add(jen.Return(jen.Id("size"))) + }) + return f, 0 +} + +func (sizegen *sizegen) sizeImplForBasic(name *types.TypeName, st *types.Basic) (jen.Code, codeFlag) { + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0))))) + b.Add(jen.Id("size").Op(":=").Lit(int64(0))) + b.Add(jen.If(jen.Id("alloc")).Block( + jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(st)))), + )) + if st.Info()&types.IsString != 0 { + b.Add(jen.Id("size").Op("+=").Do(mallocsize(jen.Int64().Call(jen.Len(jen.Op("*").Add(jen.Id("cached"))))))) + } + b.Add(jen.Return(jen.Id("size"))) + }) + return f, 0 +} + +func (sizegen *sizegen) sizeImplForSignature(name *types.TypeName, _ *types.Signature) (jen.Code, codeFlag) { + f := jen.Func() + f.Params(jen.Id("cached").Op("*").Id(name.Name())) + f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64() + f.BlockFunc(func(b *jen.Group) { + // assume that function pointers do not allocate (although they might, if they're closures) + b.Add(jen.Return(jen.Lit(int64(0)))) + }) + return f, 0 +} + func (sizegen *sizegen) sizeStmtForMap(fieldName *jen.Statement, m *types.Map) []jen.Code { const bucketCnt = 8 const sizeofHmap = int64(6 * 8) @@ -445,12 +549,21 @@ func (sizegen *sizegen) sizeStmtForType(fieldName *jen.Statement, field types.Ty ts := sizegen.getKnownType(node) if ts.pod || !ts.local { if alloc { - if !ts.local { - log.Printf("WARNING: size of external type %s cannot be fully calculated", node) + var stmts []jen.Code + if node.String() == "math/big.Int" { + // This type is not accessible, but with the given + // accessors we can compute a proper size. + stmts = append(stmts, jen.Id("size"). + Op("+="). + Do(mallocsize(jen.Int64().Call(jen.Cap(fieldName.Clone().Dot("Bits").Call())). + Op("*"). + Lit(4), + ))) + } else if !ts.local { + stmts = append(stmts, jen.Commentf("WARNING: size of external type %s cannot be fully calculated", node)) } - return jen.If(fieldName.Clone().Op("!=").Nil()).Block( - jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(node.Underlying())))), - ), 0 + stmts = append(stmts, jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(node.Underlying()))))) + return jen.If(fieldName.Clone().Op("!=").Nil()).Block(stmts...), 0 } return nil, 0 } @@ -490,15 +603,16 @@ func (sizegen *sizegen) sizeStmtForType(fieldName *jen.Statement, field types.Ty // assume that function pointers do not allocate (although they might, if they're closures) return nil, 0 + case *types.Alias: + return sizegen.sizeStmtForType(fieldName, types.Unalias(node), alloc) + default: - log.Printf("unhandled type: %T", node) - return nil, 0 + panic(fmt.Sprintf("unhandled type: %v (%T)", node, node)) } } var defaultGenTypes = []string{ "vitess.io/vitess/go/pools/smartconnpool.Setting", - "vitess.io/vitess/go/vt/schema.DDLStrategySetting", "vitess.io/vitess/go/vt/vtgate/engine.Plan", "vitess.io/vitess/go/vt/vttablet/tabletserver.TabletPlan", "vitess.io/vitess/go/sqltypes.Result", diff --git a/go/viperutil/config.go b/go/viperutil/config.go index 49e3f960875..33cc112b4af 100644 --- a/go/viperutil/config.go +++ b/go/viperutil/config.go @@ -18,6 +18,7 @@ package viperutil import ( "context" + "errors" "fmt" "os" "reflect" @@ -162,19 +163,19 @@ func LoadConfig() (context.CancelFunc, error) { } if err != nil { - if nferr, ok := err.(viper.ConfigFileNotFoundError); ok { + if isConfigFileNotFoundError(err) { msg := "Failed to read in config %s: %s" switch configFileNotFoundHandling.Get() { case WarnOnConfigFileNotFound: msg += ". This is optional, and can be ignored if you are not using config files. For a detailed explanation, see https://github.com/vitessio/vitess/blob/main/doc/viper/viper.md#config-files." - log.WARN(msg, registry.Static.ConfigFileUsed(), nferr.Error()) + log.WARN(msg, registry.Static.ConfigFileUsed(), err.Error()) fallthrough // after warning, ignore the error case IgnoreConfigFileNotFound: - err = nil + return func() {}, nil case ErrorOnConfigFileNotFound: - log.ERROR(msg, registry.Static.ConfigFileUsed(), nferr.Error()) + log.ERROR(msg, registry.Static.ConfigFileUsed(), err.Error()) case ExitOnConfigFileNotFound: - log.CRITICAL(msg, registry.Static.ConfigFileUsed(), nferr.Error()) + log.CRITICAL(msg, registry.Static.ConfigFileUsed(), err.Error()) } } } @@ -186,6 +187,14 @@ func LoadConfig() (context.CancelFunc, error) { return registry.Dynamic.Watch(context.Background(), registry.Static, configPersistenceMinInterval.Get()) } +// isConfigFileNotFoundError checks if the error is caused because the file wasn't found. +func isConfigFileNotFoundError(err error) bool { + if errors.As(err, &viper.ConfigFileNotFoundError{}) { + return true + } + return errors.Is(err, os.ErrNotExist) +} + // NotifyConfigReload adds a subscription that the dynamic registry will attempt // to notify on config changes. The notification fires after the updated config // has been loaded from disk into the live config. diff --git a/go/viperutil/config_test.go b/go/viperutil/config_test.go index 8e00a4700ac..4b67f0791f5 100644 --- a/go/viperutil/config_test.go +++ b/go/viperutil/config_test.go @@ -47,3 +47,60 @@ duration: 10h assert.Equal(t, IgnoreConfigFileNotFound, getHandlingValueFunc("duration"), "failed to get value on duration key") assert.Equal(t, ExitOnConfigFileNotFound, getHandlingValueFunc("default"), "failed to get value on default key") } + +// TestLoadConfig tests that LoadConfig behaves in the way expected when the config file doesn't exist. +func TestLoadConfig(t *testing.T) { + origConfigFile := configFile.Get() + origConfigName := configName.Get() + origConfigFileNotFoundHandling := configFileNotFoundHandling.Get() + defer func() { + configFile.Set(origConfigFile) + configName.Set(origConfigName) + configFileNotFoundHandling.Set(origConfigFileNotFoundHandling) + }() + + t.Run("Ignore file not found error", func(t *testing.T) { + configFile.Set("notfound.yaml") + configFileNotFoundHandling.Set(IgnoreConfigFileNotFound) + _, err := LoadConfig() + require.NoError(t, err) + }) + + t.Run("Ignore file not found error from config name", func(t *testing.T) { + configFile.Set("") + configName.Set("notfound") + configFileNotFoundHandling.Set(IgnoreConfigFileNotFound) + _, err := LoadConfig() + require.NoError(t, err) + }) + + t.Run("Warn file not found error", func(t *testing.T) { + configFile.Set("notfound.yaml") + configFileNotFoundHandling.Set(WarnOnConfigFileNotFound) + _, err := LoadConfig() + require.NoError(t, err) + }) + + t.Run("Ignore file not found error from config name", func(t *testing.T) { + configFile.Set("") + configName.Set("notfound") + configFileNotFoundHandling.Set(WarnOnConfigFileNotFound) + _, err := LoadConfig() + require.NoError(t, err) + }) + + t.Run("Error file not found error", func(t *testing.T) { + configFile.Set("notfound.yaml") + configFileNotFoundHandling.Set(ErrorOnConfigFileNotFound) + _, err := LoadConfig() + require.Error(t, err) + }) + + t.Run("Ignore file not found error from config name", func(t *testing.T) { + configFile.Set("") + configName.Set("notfound") + configFileNotFoundHandling.Set(ErrorOnConfigFileNotFound) + _, err := LoadConfig() + require.Error(t, err) + }) +} diff --git a/go/viperutil/internal/sync/sync.go b/go/viperutil/internal/sync/sync.go index 6bee1a14e72..f69829f734d 100644 --- a/go/viperutil/internal/sync/sync.go +++ b/go/viperutil/internal/sync/sync.go @@ -86,7 +86,7 @@ func (v *Viper) Set(key string, value any) { v.m.Lock() defer v.m.Unlock() - // We must not update v.disk here; explicit calls to Set will supercede all + // We must not update v.disk here; explicit calls to Set will supersede all // future config reloads. v.live.Set(key, value) diff --git a/go/vt/binlog/binlog_streamer.go b/go/vt/binlog/binlog_streamer.go index d62fcc3a915..08e06ec803c 100644 --- a/go/vt/binlog/binlog_streamer.go +++ b/go/vt/binlog/binlog_streamer.go @@ -760,7 +760,7 @@ func writeValuesAsSQL(sql *sqlparser.TrackedBuffer, tce *tableCacheEntry, rs *my } // We have real data. - value, l, err := binlog.CellValue(data, pos, tce.tm.Types[c], tce.tm.Metadata[c], &querypb.Field{Type: tce.ti.Fields[c].Type}) + value, l, err := binlog.CellValue(data, pos, tce.tm.Types[c], tce.tm.Metadata[c], &querypb.Field{Type: tce.ti.Fields[c].Type}, false) if err != nil { return keyspaceIDCell, nil, err } @@ -825,7 +825,7 @@ func writeIdentifiersAsSQL(sql *sqlparser.TrackedBuffer, tce *tableCacheEntry, r sql.WriteByte('=') // We have real data. - value, l, err := binlog.CellValue(data, pos, tce.tm.Types[c], tce.tm.Metadata[c], &querypb.Field{Type: tce.ti.Fields[c].Type}) + value, l, err := binlog.CellValue(data, pos, tce.tm.Types[c], tce.tm.Metadata[c], &querypb.Field{Type: tce.ti.Fields[c].Type}, false) if err != nil { return keyspaceIDCell, nil, err } diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index cea972e35a7..2f270bd7518 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -373,7 +373,7 @@ func NewHealthCheck(ctx context.Context, retryDelay, healthCheckTimeout time.Dur if c == "" { continue } - topoWatchers = append(topoWatchers, NewTopologyWatcher(ctx, topoServer, hc, filters, c, refreshInterval, refreshKnownTablets, topo.DefaultConcurrency)) + topoWatchers = append(topoWatchers, NewTopologyWatcher(ctx, topoServer, hc, filters, c, refreshInterval, refreshKnownTablets)) } hc.topoWatchers = topoWatchers diff --git a/go/vt/discovery/replicationlag.go b/go/vt/discovery/replicationlag.go index 9592440196a..7814be8ca83 100644 --- a/go/vt/discovery/replicationlag.go +++ b/go/vt/discovery/replicationlag.go @@ -28,10 +28,9 @@ import ( ) var ( - configKey = viperutil.KeyPrefixFunc("discovery") // lowReplicationLag defines the duration that replication lag is low enough that the VTTablet is considered healthy. lowReplicationLag = viperutil.Configure( - configKey("low_replication_lag"), + "discovery_low_replication_lag", viperutil.Options[time.Duration]{ FlagName: "discovery_low_replication_lag", Default: 30 * time.Second, @@ -39,7 +38,7 @@ var ( }, ) highReplicationLagMinServing = viperutil.Configure( - configKey("high_replication_lag"), + "discovery_high_replication_lag", viperutil.Options[time.Duration]{ FlagName: "discovery_high_replication_lag_minimum_serving", Default: 2 * time.Hour, @@ -47,7 +46,7 @@ var ( }, ) minNumTablets = viperutil.Configure( - configKey("min_number_serving_vttablets"), + "discovery_min_number_serving_vttablets", viperutil.Options[int]{ FlagName: "min_number_serving_vttablets", Default: 2, @@ -55,7 +54,7 @@ var ( }, ) legacyReplicationLagAlgorithm = viperutil.Configure( - configKey("legacy_replication_lag_algorithm"), + "discovery_legacy_replication_lag_algorithm", viperutil.Options[bool]{ FlagName: "legacy_replication_lag_algorithm", Default: true, diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go index c48905be948..cfe1ba2e964 100644 --- a/go/vt/discovery/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -387,8 +387,13 @@ func (tp *TabletPicker) GetMatchingTablets(ctx context.Context) []*topo.TabletIn log.Errorf("Error getting shard %s/%s: %v", tp.keyspace, tp.shard, err) return nil } - if _, ignore := tp.ignoreTablets[si.PrimaryAlias.String()]; !ignore { - aliases = append(aliases, si.PrimaryAlias) + + // It is possible that there is a cluster event (ERS/PRS, for example) due to which + // there is no primary elected for the shard at the moment. + if si.PrimaryAlias != nil { + if _, ignore := tp.ignoreTablets[si.PrimaryAlias.String()]; !ignore { + aliases = append(aliases, si.PrimaryAlias) + } } } else { actualCells := make([]string, 0) @@ -425,6 +430,9 @@ func (tp *TabletPicker) GetMatchingTablets(ctx context.Context) []*topo.TabletIn continue } for _, node := range sri.Nodes { + if node.TabletAlias == nil { + continue + } if _, ignore := tp.ignoreTablets[node.TabletAlias.String()]; !ignore { aliases = append(aliases, node.TabletAlias) } diff --git a/go/vt/discovery/tablet_picker_test.go b/go/vt/discovery/tablet_picker_test.go index 76a8828afec..27c4d8bf7b1 100644 --- a/go/vt/discovery/tablet_picker_test.go +++ b/go/vt/discovery/tablet_picker_test.go @@ -62,6 +62,29 @@ func TestPickPrimary(t *testing.T) { assert.True(t, proto.Equal(want, tablet), "Pick: %v, want %v", tablet, want) } +// TestPickNoPrimary confirms that if the picker was setup only for primary tablets but +// there is no primary setup for the shard we correctly return an error. +func TestPickNoPrimary(t *testing.T) { + defer utils.EnsureNoLeaks(t) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + te := newPickerTestEnv(t, ctx, []string{"cell", "otherCell"}) + want := addTablet(ctx, te, 100, topodatapb.TabletType_PRIMARY, "cell", true, true) + defer deleteTablet(t, te, want) + _, err := te.topoServ.UpdateShardFields(ctx, te.keyspace, te.shard, func(si *topo.ShardInfo) error { + si.PrimaryAlias = nil // force a missing primary + return nil + }) + require.NoError(t, err) + + tp, err := NewTabletPicker(ctx, te.topoServ, []string{"otherCell"}, "cell", te.keyspace, te.shard, "primary", TabletPickerOptions{}) + require.NoError(t, err) + + _, err = tp.PickForStreaming(ctx) + require.Errorf(t, err, "No healthy serving tablet") +} + func TestPickLocalPreferences(t *testing.T) { defer utils.EnsureNoLeaks(t) type tablet struct { diff --git a/go/vt/discovery/topology_watcher.go b/go/vt/discovery/topology_watcher.go index 64346d524ad..d1e358e1aa5 100644 --- a/go/vt/discovery/topology_watcher.go +++ b/go/vt/discovery/topology_watcher.go @@ -26,16 +26,13 @@ import ( "sync" "time" - "vitess.io/vitess/go/vt/topo/topoproto" - - "vitess.io/vitess/go/vt/key" - "vitess.io/vitess/go/stats" "vitess.io/vitess/go/trace" - + "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/proto/topodata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" ) const ( @@ -56,7 +53,7 @@ var ( // tabletInfo is used internally by the TopologyWatcher struct. type tabletInfo struct { alias string - tablet *topodata.Tablet + tablet *topodatapb.Tablet } // TopologyWatcher polls the topology periodically for changes to @@ -70,7 +67,6 @@ type TopologyWatcher struct { cell string refreshInterval time.Duration refreshKnownTablets bool - concurrency int ctx context.Context cancelFunc context.CancelFunc // wg keeps track of all launched Go routines. @@ -92,7 +88,7 @@ type TopologyWatcher struct { // NewTopologyWatcher returns a TopologyWatcher that monitors all // the tablets in a cell, and reloads them as needed. -func NewTopologyWatcher(ctx context.Context, topoServer *topo.Server, hc HealthCheck, f TabletFilter, cell string, refreshInterval time.Duration, refreshKnownTablets bool, topoReadConcurrency int) *TopologyWatcher { +func NewTopologyWatcher(ctx context.Context, topoServer *topo.Server, hc HealthCheck, f TabletFilter, cell string, refreshInterval time.Duration, refreshKnownTablets bool) *TopologyWatcher { tw := &TopologyWatcher{ topoServer: topoServer, healthcheck: hc, @@ -100,7 +96,6 @@ func NewTopologyWatcher(ctx context.Context, topoServer *topo.Server, hc HealthC cell: cell, refreshInterval: refreshInterval, refreshKnownTablets: refreshKnownTablets, - concurrency: topoReadConcurrency, tablets: make(map[string]*tabletInfo), } tw.firstLoadChan = make(chan struct{}) @@ -112,7 +107,7 @@ func NewTopologyWatcher(ctx context.Context, topoServer *topo.Server, hc HealthC } func (tw *TopologyWatcher) getTablets() ([]*topo.TabletInfo, error) { - return tw.topoServer.GetTabletsByCell(tw.ctx, tw.cell, &topo.GetTabletsByCellOptions{Concurrency: tw.concurrency}) + return tw.topoServer.GetTabletsByCell(tw.ctx, tw.cell, nil) } // Start starts the topology watcher. @@ -271,14 +266,14 @@ func (tw *TopologyWatcher) TopoChecksum() uint32 { // to be applied as an additional filter on the list of tablets returned by its getTablets function. type TabletFilter interface { // IsIncluded returns whether tablet is included in this filter - IsIncluded(tablet *topodata.Tablet) bool + IsIncluded(tablet *topodatapb.Tablet) bool } // TabletFilters contains filters for tablets. type TabletFilters []TabletFilter // IsIncluded returns true if a tablet passes all filters. -func (tf TabletFilters) IsIncluded(tablet *topodata.Tablet) bool { +func (tf TabletFilters) IsIncluded(tablet *topodatapb.Tablet) bool { for _, filter := range tf { if !filter.IsIncluded(tablet) { return false @@ -299,7 +294,7 @@ type FilterByShard struct { type filterShard struct { keyspace string shard string - keyRange *topodata.KeyRange // only set if shard is also a KeyRange + keyRange *topodatapb.KeyRange // only set if shard is also a KeyRange } // NewFilterByShard creates a new FilterByShard for use by a @@ -344,7 +339,7 @@ func NewFilterByShard(filters []string) (*FilterByShard, error) { } // IsIncluded returns true iff the tablet's keyspace and shard match what we have. -func (fbs *FilterByShard) IsIncluded(tablet *topodata.Tablet) bool { +func (fbs *FilterByShard) IsIncluded(tablet *topodatapb.Tablet) bool { canonical, kr, err := topo.ValidateShardName(tablet.Shard) if err != nil { log.Errorf("Error parsing shard name %v, will ignore tablet: %v", tablet.Shard, err) @@ -384,7 +379,7 @@ func NewFilterByKeyspace(selectedKeyspaces []string) *FilterByKeyspace { } // IsIncluded returns true if the tablet's keyspace matches what we have. -func (fbk *FilterByKeyspace) IsIncluded(tablet *topodata.Tablet) bool { +func (fbk *FilterByKeyspace) IsIncluded(tablet *topodatapb.Tablet) bool { _, exist := fbk.keyspaces[tablet.Keyspace] return exist } @@ -403,7 +398,7 @@ func NewFilterByTabletTags(tabletTags map[string]string) *FilterByTabletTags { } // IsIncluded returns true if the tablet's tags match what we expect. -func (fbtg *FilterByTabletTags) IsIncluded(tablet *topodata.Tablet) bool { +func (fbtg *FilterByTabletTags) IsIncluded(tablet *topodatapb.Tablet) bool { if fbtg.tags == nil { return true } diff --git a/go/vt/discovery/topology_watcher_test.go b/go/vt/discovery/topology_watcher_test.go index cef367c9b74..89a656c0982 100644 --- a/go/vt/discovery/topology_watcher_test.go +++ b/go/vt/discovery/topology_watcher_test.go @@ -67,7 +67,7 @@ func TestStartAndCloseTopoWatcher(t *testing.T) { fhc := NewFakeHealthCheck(nil) defer fhc.Close() topologyWatcherOperations.ZeroAll() - tw := NewTopologyWatcher(context.Background(), ts, fhc, nil, "aa", 100*time.Microsecond, true, 5) + tw := NewTopologyWatcher(context.Background(), ts, fhc, nil, "aa", 100*time.Microsecond, true) done := make(chan bool, 3) result := make(chan bool, 1) @@ -127,7 +127,7 @@ func checkWatcher(t *testing.T, refreshKnownTablets bool) { logger := logutil.NewMemoryLogger() topologyWatcherOperations.ZeroAll() counts := topologyWatcherOperations.Counts() - tw := NewTopologyWatcher(context.Background(), ts, fhc, filter, "aa", 10*time.Minute, refreshKnownTablets, 5) + tw := NewTopologyWatcher(context.Background(), ts, fhc, filter, "aa", 10*time.Minute, refreshKnownTablets) counts = checkOpCounts(t, counts, map[string]int64{}) checkChecksum(t, tw, 0) @@ -421,7 +421,7 @@ func TestFilterByKeyspace(t *testing.T) { f := TabletFilters{NewFilterByKeyspace(testKeyspacesToWatch)} ts := memorytopo.NewServer(ctx, testCell) defer ts.Close() - tw := NewTopologyWatcher(context.Background(), ts, hc, f, testCell, 10*time.Minute, true, 5) + tw := NewTopologyWatcher(context.Background(), ts, hc, f, testCell, 10*time.Minute, true) for _, test := range testFilterByKeyspace { // Add a new tablet to the topology. @@ -502,7 +502,7 @@ func TestFilterByKeyspaceSkipsIgnoredTablets(t *testing.T) { topologyWatcherOperations.ZeroAll() counts := topologyWatcherOperations.Counts() f := TabletFilters{NewFilterByKeyspace(testKeyspacesToWatch)} - tw := NewTopologyWatcher(context.Background(), ts, fhc, f, "aa", 10*time.Minute, false /*refreshKnownTablets*/, 5) + tw := NewTopologyWatcher(context.Background(), ts, fhc, f, "aa", 10*time.Minute, false /*refreshKnownTablets*/) counts = checkOpCounts(t, counts, map[string]int64{}) checkChecksum(t, tw, 0) @@ -639,7 +639,7 @@ func TestGetTabletErrorDoesNotRemoveFromHealthcheck(t *testing.T) { defer fhc.Close() topologyWatcherOperations.ZeroAll() counts := topologyWatcherOperations.Counts() - tw := NewTopologyWatcher(context.Background(), ts, fhc, nil, "aa", 10*time.Minute, true, 5) + tw := NewTopologyWatcher(context.Background(), ts, fhc, nil, "aa", 10*time.Minute, true) defer tw.Stop() // Force fallback to getting tablets individually. diff --git a/go/vt/key/key.go b/go/vt/key/key.go index dcdcda47f81..82852daa16e 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -90,6 +90,19 @@ func Empty(id []byte) bool { // KeyRange helper methods // +// Make a Key Range +func NewKeyRange(start []byte, end []byte) *topodatapb.KeyRange { + return &topodatapb.KeyRange{Start: start, End: end} +} + +// NewCompleteKeyRange returns a complete key range. +func NewCompleteKeyRange() *topodatapb.KeyRange { + return &topodatapb.KeyRange{ + Start: nil, + End: nil, + } +} + // KeyRangeAdd adds two adjacent KeyRange values (in any order) into a single value. If the values are not adjacent, // it returns false. func KeyRangeAdd(a, b *topodatapb.KeyRange) (*topodatapb.KeyRange, bool) { diff --git a/go/vt/log/log.go b/go/vt/log/log.go index 79be1da464c..fb0c90bbb1c 100644 --- a/go/vt/log/log.go +++ b/go/vt/log/log.go @@ -111,3 +111,94 @@ func (lrms *logRotateMaxSize) String() string { func (lrms *logRotateMaxSize) Type() string { return "uint64" } + +type PrefixedLogger struct { + prefix string +} + +func NewPrefixedLogger(prefix string) *PrefixedLogger { + return &PrefixedLogger{prefix: prefix + ": "} +} + +func (pl *PrefixedLogger) V(level glog.Level) glog.Verbose { + return V(level) +} + +func (pl *PrefixedLogger) Flush() { + Flush() +} + +func (pl *PrefixedLogger) Info(args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Info(args...) +} + +func (pl *PrefixedLogger) Infof(format string, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Infof("%s"+format, args...) +} + +func (pl *PrefixedLogger) InfoDepth(depth int, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + InfoDepth(depth, args...) +} + +func (pl *PrefixedLogger) Warning(args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Warning(args...) +} + +func (pl *PrefixedLogger) Warningf(format string, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Warningf("%s"+format, args...) +} + +func (pl *PrefixedLogger) WarningDepth(depth int, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + WarningDepth(depth, args...) +} + +func (pl *PrefixedLogger) Error(args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Error(args...) +} + +func (pl *PrefixedLogger) Errorf(format string, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Errorf("%s"+format, args...) +} + +func (pl *PrefixedLogger) ErrorDepth(depth int, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + ErrorDepth(depth, args...) +} + +func (pl *PrefixedLogger) Exit(args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Exit(args...) +} + +func (pl *PrefixedLogger) Exitf(format string, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Exitf("%s"+format, args...) +} + +func (pl *PrefixedLogger) ExitDepth(depth int, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + ExitDepth(depth, args...) +} + +func (pl *PrefixedLogger) Fatal(args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Fatal(args...) +} + +func (pl *PrefixedLogger) Fatalf(format string, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + Fatalf("%s"+format, args...) +} + +func (pl *PrefixedLogger) FatalDepth(depth int, args ...any) { + args = append([]interface{}{pl.prefix}, args...) + FatalDepth(depth, args...) +} diff --git a/go/vt/logutil/logger.go b/go/vt/logutil/logger.go index 47c3f124238..46d7c0052da 100644 --- a/go/vt/logutil/logger.go +++ b/go/vt/logutil/logger.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "runtime" + "slices" "strings" "sync" "time" @@ -246,6 +247,12 @@ func (ml *MemoryLogger) Clear() { ml.mu.Unlock() } +func (ml *MemoryLogger) LogEvents() []*logutilpb.Event { + ml.mu.Lock() + defer ml.mu.Unlock() + return slices.Clone(ml.Events) +} + // LoggerWriter is an adapter that implements the io.Writer interface. type LoggerWriter struct { logger Logger diff --git a/go/vt/mysqlctl/azblobbackupstorage/azblob.go b/go/vt/mysqlctl/azblobbackupstorage/azblob.go index 3ba6b187a2f..dbd146495e8 100644 --- a/go/vt/mysqlctl/azblobbackupstorage/azblob.go +++ b/go/vt/mysqlctl/azblobbackupstorage/azblob.go @@ -32,8 +32,9 @@ import ( "github.com/Azure/azure-storage-blob-go/azblob" "github.com/spf13/pflag" + "vitess.io/vitess/go/vt/mysqlctl/errors" + "vitess.io/vitess/go/viperutil" - "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/servenv" @@ -203,9 +204,9 @@ type AZBlobBackupHandle struct { name string readOnly bool waitGroup sync.WaitGroup - errors concurrency.AllErrorRecorder ctx context.Context cancel context.CancelFunc + errors.PerFileErrorRecorder } // Directory implements BackupHandle. @@ -218,21 +219,6 @@ func (bh *AZBlobBackupHandle) Name() string { return bh.name } -// RecordError is part of the concurrency.ErrorRecorder interface. -func (bh *AZBlobBackupHandle) RecordError(err error) { - bh.errors.RecordError(err) -} - -// HasErrors is part of the concurrency.ErrorRecorder interface. -func (bh *AZBlobBackupHandle) HasErrors() bool { - return bh.errors.HasErrors() -} - -// Error is part of the concurrency.ErrorRecorder interface. -func (bh *AZBlobBackupHandle) Error() error { - return bh.errors.Error() -} - // AddFile implements BackupHandle. func (bh *AZBlobBackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { if bh.readOnly { @@ -263,7 +249,7 @@ func (bh *AZBlobBackupHandle) AddFile(ctx context.Context, filename string, file }) if err != nil { reader.CloseWithError(err) - bh.RecordError(err) + bh.RecordError(filename, err) } }() diff --git a/go/vt/mysqlctl/backupengine.go b/go/vt/mysqlctl/backupengine.go index fb3d0e2d125..eeb14039d01 100644 --- a/go/vt/mysqlctl/backupengine.go +++ b/go/vt/mysqlctl/backupengine.go @@ -272,7 +272,7 @@ func getBackupManifestInto(ctx context.Context, backup backupstorage.BackupHandl if err := json.NewDecoder(file).Decode(outManifest); err != nil { return vterrors.Wrap(err, "can't decode MANIFEST") } - return nil + return backup.Error() } // IncrementalBackupDetails lists some incremental backup specific information diff --git a/go/vt/mysqlctl/backupstorage/interface.go b/go/vt/mysqlctl/backupstorage/interface.go index 92bc71d63aa..4fd37b3163a 100644 --- a/go/vt/mysqlctl/backupstorage/interface.go +++ b/go/vt/mysqlctl/backupstorage/interface.go @@ -25,7 +25,8 @@ import ( "github.com/spf13/pflag" - "vitess.io/vitess/go/vt/concurrency" + "vitess.io/vitess/go/vt/mysqlctl/errors" + "vitess.io/vitess/go/vt/servenv" ) @@ -89,9 +90,9 @@ type BackupHandle interface { // ReadCloser is closed. ReadFile(ctx context.Context, filename string) (io.ReadCloser, error) - // concurrency.ErrorRecorder is embedded here to coordinate reporting and - // handling of errors among all the components involved in taking a backup. - concurrency.ErrorRecorder + // BackupErrorRecorder is embedded here to coordinate reporting and + // handling of errors among all the components involved in taking/restoring a backup. + errors.BackupErrorRecorder } // BackupStorage is the interface to the storage system diff --git a/go/vt/mysqlctl/backup_blackbox_race_test.go b/go/vt/mysqlctl/blackbox/backup_race_test.go similarity index 97% rename from go/vt/mysqlctl/backup_blackbox_race_test.go rename to go/vt/mysqlctl/blackbox/backup_race_test.go index 5414ebc5fa6..fd39dfe4b06 100644 --- a/go/vt/mysqlctl/backup_blackbox_race_test.go +++ b/go/vt/mysqlctl/blackbox/backup_race_test.go @@ -16,8 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package mysqlctl_test is the blackbox tests for package mysqlctl. -package mysqlctl_test +// Package blackbox is the blackbox tests for package mysqlctl. +package blackbox import ( "fmt" @@ -75,7 +75,7 @@ func TestExecuteBackupWithFailureOnLastFile(t *testing.T) { require.NoError(t, createBackupFiles(path.Join(dataDir, "test2"), 2, "ibd")) defer os.RemoveAll(backupRoot) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { fpath := path.Join("log", mysql.DynamicRedoLogSubdir) @@ -144,7 +144,7 @@ func TestExecuteBackupWithFailureOnLastFile(t *testing.T) { TopoServer: ts, Keyspace: keyspace, Shard: shard, - MysqlShutdownTimeout: mysqlShutdownTimeout, + MysqlShutdownTimeout: MysqlShutdownTimeout, }, bh) require.ErrorContains(t, err, "cannot add file: 3") diff --git a/go/vt/mysqlctl/backup_blackbox_test.go b/go/vt/mysqlctl/blackbox/backup_test.go similarity index 57% rename from go/vt/mysqlctl/backup_blackbox_test.go rename to go/vt/mysqlctl/blackbox/backup_test.go index 15244fb8782..b7e35304904 100644 --- a/go/vt/mysqlctl/backup_blackbox_test.go +++ b/go/vt/mysqlctl/blackbox/backup_test.go @@ -14,12 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package mysqlctl_test is the blackbox tests for package mysqlctl. -package mysqlctl_test +// Package blackbox is the blackbox tests for package mysqlctl. +package blackbox import ( + "bytes" "context" + "errors" "fmt" + "io" "os" "path" "strings" @@ -31,7 +34,6 @@ import ( "vitess.io/vitess/go/test/utils" - "vitess.io/vitess/go/mysql/capabilities" "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/sqltypes" @@ -48,40 +50,6 @@ import ( "vitess.io/vitess/go/vt/topo/memorytopo" ) -const mysqlShutdownTimeout = 1 * time.Minute - -func setBuiltinBackupMysqldDeadline(t time.Duration) time.Duration { - old := mysqlctl.BuiltinBackupMysqldTimeout - mysqlctl.BuiltinBackupMysqldTimeout = t - - return old -} - -func createBackupDir(root string, dirs ...string) error { - for _, dir := range dirs { - if err := os.MkdirAll(path.Join(root, dir), 0755); err != nil { - return err - } - } - - return nil -} - -func createBackupFiles(root string, fileCount int, ext string) error { - for i := 0; i < fileCount; i++ { - f, err := os.Create(path.Join(root, fmt.Sprintf("%d.%s", i, ext))) - if err != nil { - return err - } - if _, err := f.Write([]byte("hello, world!")); err != nil { - return err - } - defer f.Close() - } - - return nil -} - func TestExecuteBackup(t *testing.T) { ctx := utils.LeakCheckContext(t) @@ -97,7 +65,7 @@ func TestExecuteBackup(t *testing.T) { require.NoError(t, createBackupFiles(path.Join(dataDir, "test2"), 2, "ibd")) defer os.RemoveAll(backupRoot) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { fpath := path.Join("log", mysql.DynamicRedoLogSubdir) @@ -133,8 +101,8 @@ func TestExecuteBackup(t *testing.T) { be := &mysqlctl.BuiltinBackupEngine{} // Configure a tight deadline to force a timeout - oldDeadline := setBuiltinBackupMysqldDeadline(time.Second) - defer setBuiltinBackupMysqldDeadline(oldDeadline) + oldDeadline := SetBuiltinBackupMysqldDeadline(time.Second) + defer SetBuiltinBackupMysqldDeadline(oldDeadline) bh := filebackupstorage.NewBackupHandle(nil, "", "", false) @@ -163,7 +131,7 @@ func TestExecuteBackup(t *testing.T) { Keyspace: keyspace, Shard: shard, Stats: fakeStats, - MysqlShutdownTimeout: mysqlShutdownTimeout, + MysqlShutdownTimeout: MysqlShutdownTimeout, }, bh) require.NoError(t, err) @@ -221,7 +189,7 @@ func TestExecuteBackup(t *testing.T) { TopoServer: ts, Keyspace: keyspace, Shard: shard, - MysqlShutdownTimeout: mysqlShutdownTimeout, + MysqlShutdownTimeout: MysqlShutdownTimeout, }, bh) assert.Error(t, err) @@ -243,7 +211,7 @@ func TestExecuteBackupWithSafeUpgrade(t *testing.T) { require.NoError(t, createBackupFiles(path.Join(dataDir, "test2"), 2, "ibd")) defer os.RemoveAll(backupRoot) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { fpath := path.Join("log", mysql.DynamicRedoLogSubdir) @@ -279,8 +247,8 @@ func TestExecuteBackupWithSafeUpgrade(t *testing.T) { be := &mysqlctl.BuiltinBackupEngine{} // Configure a tight deadline to force a timeout - oldDeadline := setBuiltinBackupMysqldDeadline(time.Second) - defer setBuiltinBackupMysqldDeadline(oldDeadline) + oldDeadline := SetBuiltinBackupMysqldDeadline(time.Second) + defer SetBuiltinBackupMysqldDeadline(oldDeadline) bh := filebackupstorage.NewBackupHandle(nil, "", "", false) @@ -310,7 +278,7 @@ func TestExecuteBackupWithSafeUpgrade(t *testing.T) { Shard: shard, Stats: backupstats.NewFakeStats(), UpgradeSafe: true, - MysqlShutdownTimeout: mysqlShutdownTimeout, + MysqlShutdownTimeout: MysqlShutdownTimeout, }, bh) require.NoError(t, err) @@ -336,7 +304,7 @@ func TestExecuteBackupWithCanceledContext(t *testing.T) { require.NoError(t, createBackupFiles(path.Join(dataDir, "test2"), 2, "ibd")) defer os.RemoveAll(backupRoot) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { fpath := path.Join("log", mysql.DynamicRedoLogSubdir) @@ -397,12 +365,12 @@ func TestExecuteBackupWithCanceledContext(t *testing.T) { TopoServer: ts, Keyspace: keyspace, Shard: shard, - MysqlShutdownTimeout: mysqlShutdownTimeout, + MysqlShutdownTimeout: MysqlShutdownTimeout, }, bh) require.Error(t, err) // all four files will fail - require.ErrorContains(t, err, "context canceled;context canceled;context canceled;context canceled") + require.ErrorContains(t, err, "context canceled; context canceled; context canceled; context canceled") assert.Equal(t, mysqlctl.BackupUnusable, backupResult) } @@ -425,7 +393,7 @@ func TestExecuteRestoreWithTimedOutContext(t *testing.T) { require.NoError(t, createBackupFiles(path.Join(dataDir, "test2"), 2, "ibd")) defer os.RemoveAll(backupRoot) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { fpath := path.Join("log", mysql.DynamicRedoLogSubdir) @@ -482,7 +450,7 @@ func TestExecuteRestoreWithTimedOutContext(t *testing.T) { TopoServer: ts, Keyspace: keyspace, Shard: shard, - MysqlShutdownTimeout: mysqlShutdownTimeout, + MysqlShutdownTimeout: MysqlShutdownTimeout, }, bh) require.NoError(t, err) @@ -521,7 +489,7 @@ func TestExecuteRestoreWithTimedOutContext(t *testing.T) { RestoreToTimestamp: time.Time{}, DryRun: false, Stats: fakeStats, - MysqlShutdownTimeout: mysqlShutdownTimeout, + MysqlShutdownTimeout: MysqlShutdownTimeout, } // Successful restore. @@ -587,24 +555,374 @@ func TestExecuteRestoreWithTimedOutContext(t *testing.T) { } } -// needInnoDBRedoLogSubdir indicates whether we need to create a redo log subdirectory. -// Starting with MySQL 8.0.30, the InnoDB redo logs are stored in a subdirectory of the -// (/. by default) called "#innodb_redo". See: -// -// https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html#innodb-modifying-redo-log-capacity -func needInnoDBRedoLogSubdir() (needIt bool, err error) { - mysqldVersionStr, err := mysqlctl.GetVersionString() - if err != nil { - return needIt, err +type rwCloseFailFirstCall struct { + *bytes.Buffer + firstDone bool +} + +func (w *rwCloseFailFirstCall) Write(p []byte) (n int, err error) { + if w.firstDone { + return w.Buffer.Write(p) } - _, sv, err := mysqlctl.ParseVersionString(mysqldVersionStr) - if err != nil { - return needIt, err + w.firstDone = true + return 0, errors.New("failing first write") +} + +func (w *rwCloseFailFirstCall) Read(p []byte) (n int, err error) { + if w.firstDone { + return w.Buffer.Read(p) } - versionStr := fmt.Sprintf("%d.%d.%d", sv.Major, sv.Minor, sv.Patch) - capableOf := mysql.ServerVersionCapableOf(versionStr) - if capableOf == nil { - return needIt, fmt.Errorf("cannot determine database flavor details for version %s", versionStr) + w.firstDone = true + return 0, errors.New("failing first read") +} + +func (w *rwCloseFailFirstCall) Close() error { + return nil +} + +func newWriteCloseFailFirstWrite(firstWriteDone bool) *rwCloseFailFirstCall { + return &rwCloseFailFirstCall{ + Buffer: bytes.NewBuffer(nil), + firstDone: firstWriteDone, } - return capableOf(capabilities.DynamicRedoLogCapacityFlavorCapability) +} + +func TestExecuteBackupFailToWriteEachFileOnlyOnce(t *testing.T) { + ctx := utils.LeakCheckContext(t) + backupRoot, keyspace, shard, ts := SetupCluster(ctx, t, 2, 2) + + bufferPerFiles := make(map[string]*rwCloseFailFirstCall) + be := &mysqlctl.BuiltinBackupEngine{} + bh := &mysqlctl.FakeBackupHandle{} + bh.AddFileReturnF = func(filename string) mysqlctl.FakeBackupHandleAddFileReturn { + // This mimics what happens with the other BackupHandles where doing AddFile will either truncate or override + // any existing data if the same filename already exists. + _, isRetry := bufferPerFiles[filename] + newBuffer := newWriteCloseFailFirstWrite(isRetry) + bufferPerFiles[filename] = newBuffer + return mysqlctl.FakeBackupHandleAddFileReturn{WriteCloser: newBuffer} + } + + // Spin up a fake daemon to be used in backups. It needs to be allowed to receive: + // "STOP REPLICA", "START REPLICA", in that order. + fakedb := fakesqldb.New(t) + defer fakedb.Close() + mysqld := mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + logger := logutil.NewMemoryLogger() + ctx, cancel := context.WithCancel(ctx) + backupResult, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logger, + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + Stats: backupstats.NewFakeStats(), + Concurrency: 1, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: MysqlShutdownTimeout, + }, bh) + cancel() + + expectedLogs := []string{ + "Backing up file: test1/0.ibd (attempt 1/2)", + "Backing up file: test1/1.ibd (attempt 1/2)", + "Backing up file: test2/0.ibd (attempt 1/2)", + "Backing up file: test2/1.ibd (attempt 1/2)", + + "Backing up file: test1/0.ibd (attempt 2/2)", + "Backing up file: test1/1.ibd (attempt 2/2)", + "Backing up file: test2/0.ibd (attempt 2/2)", + "Backing up file: test2/1.ibd (attempt 2/2)", + + "Backing up file MANIFEST (attempt 1/2)", + "Failed backing up MANIFEST (attempt 1/2)", + "Backing up file MANIFEST (attempt 2/2)", + "Completed backing up MANIFEST (attempt 2/2)", + } + + // Sleep just long enough for everything to complete. + // It's not flaky, the race detector detects a race when there isn't, + // the machine is just too slow to propagate the ctxCancel() to all goroutines. + time.Sleep(2 * time.Second) + AssertLogs(t, expectedLogs, logger) + + require.NoError(t, err) + require.Equal(t, mysqlctl.BackupUsable, backupResult) +} + +func TestExecuteBackupFailToWriteFileTwice(t *testing.T) { + ctx := utils.LeakCheckContext(t) + backupRoot, keyspace, shard, ts := SetupCluster(ctx, t, 1, 1) + + bufferPerFiles := make(map[string]*rwCloseFailFirstCall) + be := &mysqlctl.BuiltinBackupEngine{} + bh := &mysqlctl.FakeBackupHandle{} + bh.AddFileReturnF = func(filename string) mysqlctl.FakeBackupHandleAddFileReturn { + newBuffer := newWriteCloseFailFirstWrite(false) + bufferPerFiles[filename] = newBuffer + + return mysqlctl.FakeBackupHandleAddFileReturn{WriteCloser: newBuffer} + } + + // Spin up a fake daemon to be used in backups. It needs to be allowed to receive: + // "STOP REPLICA", "START REPLICA", in that order. + fakedb := fakesqldb.New(t) + defer fakedb.Close() + mysqld := mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + logger := logutil.NewMemoryLogger() + fakeStats := backupstats.NewFakeStats() + ctx, cancel := context.WithCancel(ctx) + backupResult, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logger, + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + Stats: fakeStats, + Concurrency: 1, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: MysqlShutdownTimeout, + }, bh) + cancel() + + // Sleep just long enough for everything to complete. + // It's not flaky, the race detector detects a race when there isn't, + // the machine is just too slow to propagate the ctxCancel() to all goroutines. + time.Sleep(2 * time.Second) + + expectedLogs := []string{ + "Backing up file: test1/0.ibd (attempt 1/2)", + "Backing up file: test1/0.ibd (attempt 2/2)", + } + AssertLogs(t, expectedLogs, logger) + + ss := GetStats(fakeStats) + require.Equal(t, 2, ss.DestinationCloseStats) + require.Equal(t, 2, ss.DestinationOpenStats) + require.Equal(t, 2, ss.DestinationWriteStats) + require.Equal(t, 2, ss.SourceCloseStats) + require.Equal(t, 2, ss.SourceOpenStats) + require.Equal(t, 2, ss.SourceReadStats) + require.ErrorContains(t, err, "failing first write") + require.Equal(t, mysqlctl.BackupUnusable, backupResult) +} + +func TestExecuteRestoreFailToReadEachFileOnlyOnce(t *testing.T) { + ctx := utils.LeakCheckContext(t) + backupRoot, keyspace, shard, ts := SetupCluster(ctx, t, 2, 2) + + be := &mysqlctl.BuiltinBackupEngine{} + bufferPerFiles := make(map[string]*rwCloseFailFirstCall) + bh := &mysqlctl.FakeBackupHandle{} + bh.AddFileReturnF = func(filename string) mysqlctl.FakeBackupHandleAddFileReturn { + // let's never make it fail for now + newBuffer := newWriteCloseFailFirstWrite(true) + bufferPerFiles[filename] = newBuffer + return mysqlctl.FakeBackupHandleAddFileReturn{WriteCloser: newBuffer} + } + + // Spin up a fake daemon to be used in backups. It needs to be allowed to receive: + // "STOP REPLICA", "START REPLICA", in that order. + fakedb := fakesqldb.New(t) + defer fakedb.Close() + mysqld := mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + backupResult, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logutil.NewConsoleLogger(), + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + Stats: backupstats.NewFakeStats(), + Concurrency: 1, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: MysqlShutdownTimeout, + }, bh) + + require.NoError(t, err) + require.Equal(t, mysqlctl.BackupUsable, backupResult) + + // let's mark each file in the buffer as if it is their first read + for key := range bufferPerFiles { + bufferPerFiles[key].firstDone = false + } + + // Now try to restore the above backup. + fakeBh := &mysqlctl.FakeBackupHandle{} + fakeBh.ReadFileReturnF = func(ctx context.Context, filename string) (io.ReadCloser, error) { + return bufferPerFiles[filename], nil + } + + fakedb = fakesqldb.New(t) + defer fakedb.Close() + mysqld = mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + fakeStats := backupstats.NewFakeStats() + logger := logutil.NewMemoryLogger() + + restoreParams := mysqlctl.RestoreParams{ + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + BinLogPath: path.Join(backupRoot, "binlog"), + RelayLogPath: path.Join(backupRoot, "relaylog"), + RelayLogIndexPath: path.Join(backupRoot, "relaylogindex"), + RelayLogInfoPath: path.Join(backupRoot, "relayloginfo"), + }, + Logger: logger, + Mysqld: mysqld, + Concurrency: 1, + HookExtraEnv: map[string]string{}, + DeleteBeforeRestore: false, + DbName: "test", + Keyspace: "test", + Shard: "-", + StartTime: time.Now(), + RestoreToPos: replication.Position{}, + RestoreToTimestamp: time.Time{}, + DryRun: false, + Stats: fakeStats, + MysqlShutdownTimeout: MysqlShutdownTimeout, + } + + // Successful restore. + bm, err := be.ExecuteRestore(ctx, restoreParams, fakeBh) + assert.NoError(t, err) + assert.NotNil(t, bm) + + ss := GetStats(fakeStats) + require.Equal(t, 8, ss.DestinationCloseStats) + require.Equal(t, 8, ss.DestinationOpenStats) + require.Equal(t, 4, ss.DestinationWriteStats) + require.Equal(t, 8, ss.SourceCloseStats) + require.Equal(t, 8, ss.SourceOpenStats) + require.Equal(t, 8, ss.SourceReadStats) +} + +func TestExecuteRestoreFailToReadEachFileTwice(t *testing.T) { + ctx := utils.LeakCheckContext(t) + backupRoot, keyspace, shard, ts := SetupCluster(ctx, t, 2, 2) + + be := &mysqlctl.BuiltinBackupEngine{} + bufferPerFiles := make(map[string]*rwCloseFailFirstCall) + bh := &mysqlctl.FakeBackupHandle{} + bh.AddFileReturnF = func(filename string) mysqlctl.FakeBackupHandleAddFileReturn { + // let's never make it fail for now + newBuffer := newWriteCloseFailFirstWrite(true) + bufferPerFiles[filename] = newBuffer + return mysqlctl.FakeBackupHandleAddFileReturn{WriteCloser: newBuffer} + } + + // Spin up a fake daemon to be used in backups. It needs to be allowed to receive: + // "STOP REPLICA", "START REPLICA", in that order. + fakedb := fakesqldb.New(t) + defer fakedb.Close() + mysqld := mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + backupResult, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logutil.NewConsoleLogger(), + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + Stats: backupstats.NewFakeStats(), + Concurrency: 1, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: MysqlShutdownTimeout, + }, bh) + + require.NoError(t, err) + require.Equal(t, mysqlctl.BackupUsable, backupResult) + + // Now try to restore the above backup. + fakeBh := &mysqlctl.FakeBackupHandle{} + fakeBh.ReadFileReturnF = func(ctx context.Context, filename string) (io.ReadCloser, error) { + // always make it fail, expect if it is the MANIFEST file, otherwise we won't start restoring the other files + buffer := bufferPerFiles[filename] + if filename != "MANIFEST" { + buffer.firstDone = false + } + return buffer, nil + } + + fakedb = fakesqldb.New(t) + defer fakedb.Close() + mysqld = mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + fakeStats := backupstats.NewFakeStats() + logger := logutil.NewMemoryLogger() + + restoreParams := mysqlctl.RestoreParams{ + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + BinLogPath: path.Join(backupRoot, "binlog"), + RelayLogPath: path.Join(backupRoot, "relaylog"), + RelayLogIndexPath: path.Join(backupRoot, "relaylogindex"), + RelayLogInfoPath: path.Join(backupRoot, "relayloginfo"), + }, + Logger: logger, + Mysqld: mysqld, + Concurrency: 1, + HookExtraEnv: map[string]string{}, + DeleteBeforeRestore: false, + DbName: "test", + Keyspace: "test", + Shard: "-", + StartTime: time.Now(), + RestoreToPos: replication.Position{}, + RestoreToTimestamp: time.Time{}, + DryRun: false, + Stats: fakeStats, + MysqlShutdownTimeout: MysqlShutdownTimeout, + } + + // Successful restore. + bm, err := be.ExecuteRestore(ctx, restoreParams, fakeBh) + assert.ErrorContains(t, err, "failing first read") + assert.Nil(t, bm) + + ss := GetStats(fakeStats) + require.Equal(t, 5, ss.DestinationCloseStats) + require.Equal(t, 5, ss.DestinationOpenStats) + require.Equal(t, 0, ss.DestinationWriteStats) + require.Equal(t, 5, ss.SourceCloseStats) + require.Equal(t, 5, ss.SourceOpenStats) + require.Equal(t, 5, ss.SourceReadStats) } diff --git a/go/vt/mysqlctl/blackbox/utils.go b/go/vt/mysqlctl/blackbox/utils.go new file mode 100644 index 00000000000..c7d34ae3cf6 --- /dev/null +++ b/go/vt/mysqlctl/blackbox/utils.go @@ -0,0 +1,196 @@ +/* +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 blackbox + +import ( + "context" + "fmt" + "os" + "path" + "slices" + "strconv" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/mysql/capabilities" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/mysqlctl/backupstats" + "vitess.io/vitess/go/vt/mysqlctl/filebackupstorage" + logutilpb "vitess.io/vitess/go/vt/proto/logutil" + "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vttime" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +type StatSummary struct { + DestinationCloseStats int + DestinationOpenStats int + DestinationWriteStats int + SourceCloseStats int + SourceOpenStats int + SourceReadStats int +} + +func GetStats(stats *backupstats.FakeStats) StatSummary { + var ss StatSummary + + for _, sr := range stats.ScopeReturns { + switch sr.ScopeV[backupstats.ScopeOperation] { + case "Destination:Close": + ss.DestinationCloseStats += len(sr.TimedIncrementCalls) + case "Destination:Open": + ss.DestinationOpenStats += len(sr.TimedIncrementCalls) + case "Destination:Write": + if len(sr.TimedIncrementBytesCalls) > 0 { + ss.DestinationWriteStats++ + } + case "Source:Close": + ss.SourceCloseStats += len(sr.TimedIncrementCalls) + case "Source:Open": + ss.SourceOpenStats += len(sr.TimedIncrementCalls) + case "Source:Read": + if len(sr.TimedIncrementBytesCalls) > 0 { + ss.SourceReadStats++ + } + } + } + return ss +} + +func AssertLogs(t *testing.T, expectedLogs []string, logger *logutil.MemoryLogger) { + for _, log := range expectedLogs { + require.Truef(t, slices.ContainsFunc(logger.LogEvents(), func(event *logutilpb.Event) bool { + return event.GetValue() == log + }), "%s is missing from the logs", log) + } +} + +func SetupCluster(ctx context.Context, t *testing.T, dirs, filesPerDir int) (backupRoot string, keyspace string, shard string, ts *topo.Server) { + // Set up local backup directory + id := fmt.Sprintf("%d", time.Now().UnixNano()) + backupRoot = fmt.Sprintf("testdata/builtinbackup_test_%s", id) + filebackupstorage.FileBackupStorageRoot = backupRoot + require.NoError(t, createBackupDir(backupRoot, "innodb", "log", "datadir")) + dataDir := path.Join(backupRoot, "datadir") + // Add some files under data directory to force backup to execute semaphore acquire inside + // backupFiles() method (https://github.com/vitessio/vitess/blob/main/go/vt/mysqlctl/builtinbackupengine.go#L483). + for dirI := range dirs { + dirName := "test" + strconv.Itoa(dirI+1) + require.NoError(t, createBackupDir(dataDir, dirName)) + require.NoError(t, createBackupFiles(path.Join(dataDir, dirName), filesPerDir, "ibd")) + } + t.Cleanup(func() { + require.NoError(t, os.RemoveAll(backupRoot)) + }) + + needIt, err := NeedInnoDBRedoLogSubdir() + require.NoError(t, err) + if needIt { + fpath := path.Join("log", mysql.DynamicRedoLogSubdir) + if err := createBackupDir(backupRoot, fpath); err != nil { + require.Failf(t, err.Error(), "failed to create directory: %s", fpath) + } + } + + // Set up topo + keyspace, shard = "mykeyspace", "-" + ts = memorytopo.NewServer(ctx, "cell1") + t.Cleanup(func() { + ts.Close() + }) + + require.NoError(t, ts.CreateKeyspace(ctx, keyspace, &topodata.Keyspace{})) + require.NoError(t, ts.CreateShard(ctx, keyspace, shard)) + + tablet := topo.NewTablet(100, "cell1", "mykeyspace-00-80-0100") + tablet.Keyspace = keyspace + tablet.Shard = shard + + require.NoError(t, ts.CreateTablet(ctx, tablet)) + + _, err = ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error { + si.PrimaryAlias = &topodata.TabletAlias{Uid: 100, Cell: "cell1"} + + now := time.Now() + si.PrimaryTermStartTime = &vttime.Time{Seconds: int64(now.Second()), Nanoseconds: int32(now.Nanosecond())} + + return nil + }) + require.NoError(t, err) + return backupRoot, keyspace, shard, ts +} + +// NeedInnoDBRedoLogSubdir indicates whether we need to create a redo log subdirectory. +// Starting with MySQL 8.0.30, the InnoDB redo logs are stored in a subdirectory of the +// (/. by default) called "#innodb_redo". See: +// +// https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html#innodb-modifying-redo-log-capacity +func NeedInnoDBRedoLogSubdir() (needIt bool, err error) { + mysqldVersionStr, err := mysqlctl.GetVersionString() + if err != nil { + return needIt, err + } + _, sv, err := mysqlctl.ParseVersionString(mysqldVersionStr) + if err != nil { + return needIt, err + } + versionStr := fmt.Sprintf("%d.%d.%d", sv.Major, sv.Minor, sv.Patch) + capableOf := mysql.ServerVersionCapableOf(versionStr) + if capableOf == nil { + return needIt, fmt.Errorf("cannot determine database flavor details for version %s", versionStr) + } + return capableOf(capabilities.DynamicRedoLogCapacityFlavorCapability) +} + +const MysqlShutdownTimeout = 1 * time.Minute + +func SetBuiltinBackupMysqldDeadline(t time.Duration) time.Duration { + old := mysqlctl.BuiltinBackupMysqldTimeout + mysqlctl.BuiltinBackupMysqldTimeout = t + + return old +} + +func createBackupDir(root string, dirs ...string) error { + for _, dir := range dirs { + if err := os.MkdirAll(path.Join(root, dir), 0755); err != nil { + return err + } + } + + return nil +} + +func createBackupFiles(root string, fileCount int, ext string) error { + for i := 0; i < fileCount; i++ { + f, err := os.Create(path.Join(root, fmt.Sprintf("%d.%s", i, ext))) + if err != nil { + return err + } + if _, err := f.Write([]byte("hello, world!")); err != nil { + return err + } + defer f.Close() + } + + return nil +} diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index 5aa759f6f7a..2046a238400 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -29,18 +29,17 @@ import ( "os" "path" "path/filepath" - "sync" + "strconv" "sync/atomic" "time" "github.com/spf13/pflag" - "golang.org/x/sync/semaphore" + "golang.org/x/sync/errgroup" "vitess.io/vitess/go/ioutil" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/protoutil" - "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" stats "vitess.io/vitess/go/vt/mysqlctl/backupstats" @@ -60,6 +59,8 @@ const ( builtinBackupEngineName = "builtin" AutoIncrementalFromPos = "auto" dataDictionaryFile = "mysql.ibd" + + maxRetriesPerFile = 1 ) var ( @@ -149,6 +150,13 @@ type FileEntry struct { // ParentPath is an optional prefix to the Base path. If empty, it is ignored. Useful // for writing files in a temporary directory ParentPath string + + // RetryCount specifies how many times we retried restoring/backing up this FileEntry. + // If we fail to restore/backup this FileEntry, we will retry up to maxRetriesPerFile times. + // Every time the builtin backup engine retries this file, we increment this field by 1. + // We don't care about adding this information to the MANIFEST and also to not cause any compatibility issue + // we are adding the - json tag to let Go know it can ignore the field. + RetryCount int `json:"-"` } func init() { @@ -585,6 +593,11 @@ func (be *BuiltinBackupEngine) backupFiles( mysqlVersion string, incrDetails *IncrementalBackupDetails, ) (finalErr error) { + // backupFiles always wait for AddFiles to finish its work before returning, unless there has been a + // non-recoverable error in the process, in both cases we can cancel the context safely. + ctx, cancel := context.WithCancel(ctx) + defer cancel() + // Get the files to backup. // We don't care about totalSize because we add each file separately. var fes []FileEntry @@ -599,43 +612,82 @@ func (be *BuiltinBackupEngine) backupFiles( } params.Logger.Infof("found %v files to backup", len(fes)) - // Backup with the provided concurrency. - sema := semaphore.NewWeighted(int64(params.Concurrency)) - wg := sync.WaitGroup{} + // The error here can be ignored safely. Failed FileEntry's are handled in the next 'if' statement. + _ = be.backupFileEntries(ctx, fes, bh, params) + // BackupHandle supports the BackupErrorRecorder interface for tracking errors + // across any goroutines that fan out to take the backup. This means that we + // don't need a local error recorder and can put everything through the bh. + // + // This handles the scenario where bh.AddFile() encounters an error asynchronously, + // which ordinarily would be lost in the context of `be.backupFile`, i.e. if an + // error were encountered + // [here](https://github.com/vitessio/vitess/blob/d26b6c7975b12a87364e471e2e2dfa4e253c2a5b/go/vt/mysqlctl/s3backupstorage/s3.go#L139-L142). + // + // All the errors are grouped per file, if one or more files failed, we back them up + // once more concurrently, if any of the retry fail, we fail-fast by canceling the context + // and return an error. There is no reason to continue processing the other retries, if + // one of them failed. + if files := bh.GetFailedFiles(); len(files) > 0 { + newFEs := make([]FileEntry, len(fes)) + for _, file := range files { + fileNb, err := strconv.Atoi(file) + if err != nil { + return vterrors.Wrapf(err, "failed to retry file '%s'", file) + } + oldFes := fes[fileNb] + newFEs[fileNb] = FileEntry{ + Base: oldFes.Base, + Name: oldFes.Name, + ParentPath: oldFes.ParentPath, + RetryCount: 1, + } + bh.ResetErrorForFile(file) + } + err = be.backupFileEntries(ctx, newFEs, bh, params) + if err != nil { + return err + } + } + + // Backup the MANIFEST file and apply retry logic. + var manifestErr error + for currentRetry := 0; currentRetry <= maxRetriesPerFile; currentRetry++ { + manifestErr = be.backupManifest(ctx, params, bh, backupPosition, purgedPosition, fromPosition, fromBackupName, serverUUID, mysqlVersion, incrDetails, fes, currentRetry) + if manifestErr == nil { + break + } + bh.ResetErrorForFile(backupManifestFileName) + } + if manifestErr != nil { + return manifestErr + } + return nil +} + +// backupFileEntries iterates over a slice of FileEntry, backing them up concurrently up to the defined concurrency limit. +// This function will ignore empty FileEntry, allowing the retry mechanism to send a partially empty slice, to not +// mess up the index of retriable FileEntry. +// This function does not leave any background operation behind itself, all calls to bh.AddFile will be finished or canceled. +func (be *BuiltinBackupEngine) backupFileEntries(ctx context.Context, fes []FileEntry, bh backupstorage.BackupHandle, params BackupParams) error { ctxCancel, cancel := context.WithCancel(ctx) defer func() { - // We may still have operations in flight that require a valid context, such as adding files to S3. - // Unless we encountered an error, we should not cancel the context, this is taken care of later - // in the process. If we encountered an error however, we can safely cancel the context as we should - // no longer work on anything and exit fast. - if finalErr != nil { - cancel() - } + // If we reached this defer in all cases we can cancel the context. + // The only ways to get here are: a panic, an error when ending the backup, a successful backup. + // For all three options, it is safe to cancel the context, there should be no pending operations + // that 1) haven't completed, 2) we care about anymore. + cancel() }() + g := errgroup.Group{} + g.SetLimit(params.Concurrency) for i := range fes { - wg.Add(1) - go func(i int) { - defer wg.Done() + if fes[i].Name == "" { + continue + } + g.Go(func() error { fe := &fes[i] - // Wait until we are ready to go, return if we encounter an error - acqErr := sema.Acquire(ctxCancel, 1) - if acqErr != nil { - log.Errorf("Unable to acquire semaphore needed to backup file: %s, err: %s", fe.Name, acqErr.Error()) - bh.RecordError(acqErr) - cancel() - return - } - defer sema.Release(1) - - // First check if we have any error, if we have, there is no point trying backing up this file. - // We check for errors before checking if the context is canceled on purpose, if there was an - // error, the context would have been canceled already. - if bh.HasErrors() { - params.Logger.Errorf("Failed to restore files due to error: %v", bh.Error()) - return - } + name := fmt.Sprintf("%v", i) // Check for context cancellation explicitly because, the way semaphore code is written, theoretically we might // end up not throwing an error even after cancellation. Please see https://cs.opensource.google/go/x/sync/+/refs/tags/v0.1.0:semaphore/semaphore.go;l=66, @@ -644,83 +696,30 @@ func (be *BuiltinBackupEngine) backupFiles( select { case <-ctxCancel.Done(): log.Errorf("Context canceled or timed out during %q backup", fe.Name) - bh.RecordError(vterrors.Errorf(vtrpc.Code_CANCELED, "context canceled")) - return + bh.RecordError(name, vterrors.Errorf(vtrpc.Code_CANCELED, "context canceled")) + return nil default: } // Backup the individual file. - name := fmt.Sprintf("%v", i) - if err := be.backupFile(ctxCancel, params, bh, fe, name); err != nil { - bh.RecordError(err) - cancel() + var errBackupFile error + if errBackupFile = be.backupFile(ctxCancel, params, bh, fe, name); errBackupFile != nil { + bh.RecordError(name, vterrors.Wrapf(errBackupFile, "failed to backup file '%s'", name)) + if fe.RetryCount >= maxRetriesPerFile { + // this is the last attempt, and we have an error, we can cancel everything and fail fast. + cancel() + } } - }(i) + return nil + }) } + _ = g.Wait() - wg.Wait() - - // BackupHandle supports the ErrorRecorder interface for tracking errors - // across any goroutines that fan out to take the backup. This means that we - // don't need a local error recorder and can put everything through the bh. - // - // This handles the scenario where bh.AddFile() encounters an error asynchronously, - // which ordinarily would be lost in the context of `be.backupFile`, i.e. if an - // error were encountered - // [here](https://github.com/vitessio/vitess/blob/d26b6c7975b12a87364e471e2e2dfa4e253c2a5b/go/vt/mysqlctl/s3backupstorage/s3.go#L139-L142). - if bh.HasErrors() { - return bh.Error() - } - - // open the MANIFEST - wc, err := bh.AddFile(ctx, backupManifestFileName, backupstorage.FileSizeUnknown) + err := bh.EndBackup(ctx) if err != nil { - return vterrors.Wrapf(err, "cannot add %v to backup", backupManifestFileName) - } - defer func() { - closeErr := wc.Close() - if finalErr == nil { - finalErr = closeErr - } - }() - - // JSON-encode and write the MANIFEST - bm := &builtinBackupManifest{ - // Common base fields - BackupManifest: BackupManifest{ - BackupName: bh.Name(), - BackupMethod: builtinBackupEngineName, - Position: backupPosition, - PurgedPosition: purgedPosition, - FromPosition: fromPosition, - FromBackup: fromBackupName, - Incremental: !fromPosition.IsZero(), - ServerUUID: serverUUID, - TabletAlias: params.TabletAlias, - Keyspace: params.Keyspace, - Shard: params.Shard, - BackupTime: params.BackupTime.UTC().Format(time.RFC3339), - FinishedTime: time.Now().UTC().Format(time.RFC3339), - MySQLVersion: mysqlVersion, - UpgradeSafe: params.UpgradeSafe, - IncrementalDetails: incrDetails, - }, - - // Builtin-specific fields - FileEntries: fes, - SkipCompress: !backupStorageCompress, - CompressionEngine: CompressionEngineName, - ExternalDecompressor: ManifestExternalDecompressorCmd, - } - data, err := json.MarshalIndent(bm, "", " ") - if err != nil { - return vterrors.Wrapf(err, "cannot JSON encode %v", backupManifestFileName) - } - if _, err := wc.Write([]byte(data)); err != nil { - return vterrors.Wrapf(err, "cannot write %v", backupManifestFileName) + return err } - - return nil + return bh.Error() } type backupPipe struct { @@ -733,6 +732,7 @@ type backupPipe struct { crc32 hash.Hash32 nn int64 done chan struct{} + failed chan struct{} closed int32 } @@ -743,6 +743,7 @@ func newBackupWriter(filename string, writerBufferSize int, maxSize int64, w io. filename: filename, maxSize: maxSize, done: make(chan struct{}), + failed: make(chan struct{}), } } @@ -752,10 +753,16 @@ func newBackupReader(filename string, maxSize int64, r io.Reader) *backupPipe { r: r, filename: filename, done: make(chan struct{}), + failed: make(chan struct{}), maxSize: maxSize, } } +func retryToString(retry int) string { + // We convert the retry number to an attempt number, increasing retry by one, so it looks more human friendly + return fmt.Sprintf("(attempt %d/%d)", retry+1, maxRetriesPerFile+1) +} + func (bp *backupPipe) Read(p []byte) (int, error) { nn, err := bp.r.Read(p) _, _ = bp.crc32.Write(p[:nn]) @@ -770,9 +777,17 @@ func (bp *backupPipe) Write(p []byte) (int, error) { return nn, err } -func (bp *backupPipe) Close() error { +func (bp *backupPipe) Close(isDone bool) (err error) { if atomic.CompareAndSwapInt32(&bp.closed, 0, 1) { - close(bp.done) + // If we fail to Flush the writer we must report this backup as a failure. + defer func() { + if isDone && err == nil { + close(bp.done) + return + } + close(bp.failed) + }() + if bp.w != nil { if err := bp.w.Flush(); err != nil { return err @@ -786,28 +801,31 @@ func (bp *backupPipe) HashString() string { return hex.EncodeToString(bp.crc32.Sum(nil)) } -func (bp *backupPipe) ReportProgress(ctx context.Context, period time.Duration, logger logutil.Logger, restore bool) { - messageStr := "restoring " +func (bp *backupPipe) ReportProgress(ctx context.Context, period time.Duration, logger logutil.Logger, restore bool, retryStr string) { + messageStr := "restoring" if !restore { - messageStr = "backing up " + messageStr = "backing up" } tick := time.NewTicker(period) defer tick.Stop() for { select { case <-ctx.Done(): - logger.Infof("Canceled %s of %q file", messageStr, bp.filename) + logger.Infof("Canceled %s of %q file %s", messageStr, bp.filename, retryStr) return case <-bp.done: - logger.Infof("Completed %s %q", messageStr, bp.filename) + logger.Infof("Completed %s %q %s", messageStr, bp.filename, retryStr) + return + case <-bp.failed: + logger.Infof("Failed %s %q %s", messageStr, bp.filename, retryStr) return case <-tick.C: written := float64(atomic.LoadInt64(&bp.nn)) if bp.maxSize == 0 { - logger.Infof("%s %q: %.02fkb", messageStr, bp.filename, written/1024.0) + logger.Infof("%s %q %s: %.02fkb", messageStr, bp.filename, retryStr, written/1024.0) } else { maxSize := float64(bp.maxSize) - logger.Infof("%s %q: %.02f%% (%.02f/%.02fkb)", messageStr, bp.filename, 100.0*written/maxSize, written/1024.0, maxSize/1024.0) + logger.Infof("%s %q %s: %.02f%% (%.02f/%.02fkb)", messageStr, bp.filename, retryStr, 100.0*written/maxSize, written/1024.0, maxSize/1024.0) } } } @@ -815,12 +833,15 @@ func (bp *backupPipe) ReportProgress(ctx context.Context, period time.Duration, // backupFile backs up an individual file. func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle, fe *FileEntry, name string) (finalErr error) { - ctx, cancel := context.WithCancel(ctx) - defer func() { - if finalErr != nil { - cancel() - } - }() + // We need another context that does not live outside of this function. + // Reporting progress, compressing and writing are operations that will be + // over by the time we exit this function, they can use this cancelable context. + // However, AddFile is something that may continue in the background even after + // this function exits. In this case, we give it the parent context so the caller + // has more control over when to cancel AddFile. + cancelableCtx, cancel := context.WithCancel(ctx) + defer cancel() + // Open the source file for reading. openSourceAt := time.Now() source, err := fe.open(params.Cnf, true) @@ -843,11 +864,12 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupPara return err } + retryStr := retryToString(fe.RetryCount) br := newBackupReader(fe.Name, fi.Size(), timedSource) - go br.ReportProgress(ctx, builtinBackupProgress, params.Logger, false /*restore*/) + go br.ReportProgress(cancelableCtx, builtinBackupProgress, params.Logger, false /*restore*/, retryStr) // Open the destination file for writing, and a buffer. - params.Logger.Infof("Backing up file: %v", fe.Name) + params.Logger.Infof("Backing up file: %v %s", fe.Name, retryStr) openDestAt := time.Now() dest, err := bh.AddFile(ctx, name, fi.Size()) if err != nil { @@ -879,19 +901,20 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupPara defer func() { // Close the backupPipe to finish writing on destination. - if err := bw.Close(); err != nil { + if err := bw.Close(createAndCopyErr == nil); err != nil { createAndCopyErr = errors.Join(createAndCopyErr, vterrors.Wrapf(err, "cannot flush destination: %v", name)) } - if err := br.Close(); err != nil { + if err := br.Close(createAndCopyErr == nil); err != nil { createAndCopyErr = errors.Join(createAndCopyErr, vterrors.Wrap(err, "failed to close the source reader")) } + }() // Create the gzip compression pipe, if necessary. if backupStorageCompress { var compressor io.WriteCloser if ExternalCompressorCmd != "" { - compressor, err = newExternalCompressor(ctx, ExternalCompressorCmd, writer, params.Logger) + compressor, err = newExternalCompressor(cancelableCtx, ExternalCompressorCmd, writer, params.Logger) } else { compressor, err = newBuiltinCompressor(CompressionEngineName, writer, params.Logger) } @@ -902,13 +925,13 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupPara compressStats := params.Stats.Scope(stats.Operation("Compressor:Write")) writer = ioutil.NewMeteredWriter(compressor, compressStats.TimedIncrementBytes) - closer := ioutil.NewTimeoutCloser(ctx, compressor, closeTimeout) + closer := ioutil.NewTimeoutCloser(cancelableCtx, compressor, closeTimeout) defer func() { // Close gzip to flush it, after that all data is sent to writer. closeCompressorAt := time.Now() - params.Logger.Infof("closing compressor") + params.Logger.Infof("Closing compressor for file: %s %s", fe.Name, retryStr) if cerr := closer.Close(); err != nil { - cerr = vterrors.Wrapf(cerr, "failed to close compressor %v", name) + cerr = vterrors.Wrapf(cerr, "failed to close compressor %v", fe.Name) params.Logger.Error(cerr) createAndCopyErr = errors.Join(createAndCopyErr, cerr) } @@ -938,6 +961,94 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupPara return nil } +func (be *BuiltinBackupEngine) backupManifest( + ctx context.Context, + params BackupParams, + bh backupstorage.BackupHandle, + backupPosition replication.Position, + purgedPosition replication.Position, + fromPosition replication.Position, + fromBackupName string, + serverUUID string, + mysqlVersion string, + incrDetails *IncrementalBackupDetails, + fes []FileEntry, + currentAttempt int, +) (finalErr error) { + retryStr := retryToString(currentAttempt) + params.Logger.Infof("Backing up file %s %s", backupManifestFileName, retryStr) + defer func() { + state := "Completed" + if finalErr != nil { + state = "Failed" + } + params.Logger.Infof("%s backing up %s %s", state, backupManifestFileName, retryStr) + }() + + // Creating this function allows us to ensure we always close the writer no matter what, + // and in case of success that we close it before calling bh.EndBackup. + addAndWrite := func() (addAndWriteError error) { + // open the MANIFEST + wc, err := bh.AddFile(ctx, backupManifestFileName, backupstorage.FileSizeUnknown) + if err != nil { + return vterrors.Wrapf(err, "cannot add %v to backup %s", backupManifestFileName, retryStr) + } + defer func() { + if err := wc.Close(); err != nil { + addAndWriteError = errors.Join(addAndWriteError, vterrors.Wrapf(err, "cannot close backup: %v", backupManifestFileName)) + } + }() + + // JSON-encode and write the MANIFEST + bm := &builtinBackupManifest{ + // Common base fields + BackupManifest: BackupManifest{ + BackupName: bh.Name(), + BackupMethod: builtinBackupEngineName, + Position: backupPosition, + PurgedPosition: purgedPosition, + FromPosition: fromPosition, + FromBackup: fromBackupName, + Incremental: !fromPosition.IsZero(), + ServerUUID: serverUUID, + TabletAlias: params.TabletAlias, + Keyspace: params.Keyspace, + Shard: params.Shard, + BackupTime: params.BackupTime.UTC().Format(time.RFC3339), + FinishedTime: time.Now().UTC().Format(time.RFC3339), + MySQLVersion: mysqlVersion, + UpgradeSafe: params.UpgradeSafe, + IncrementalDetails: incrDetails, + }, + + // Builtin-specific fields + FileEntries: fes, + SkipCompress: !backupStorageCompress, + CompressionEngine: CompressionEngineName, + ExternalDecompressor: ManifestExternalDecompressorCmd, + } + data, err := json.MarshalIndent(bm, "", " ") + if err != nil { + return vterrors.Wrapf(err, "cannot JSON encode %v %s", backupManifestFileName, retryStr) + } + if _, err := wc.Write(data); err != nil { + return vterrors.Wrapf(err, "cannot write %v %s", backupManifestFileName, retryStr) + } + return nil + } + + err := addAndWrite() + if err != nil { + return err + } + + err = bh.EndBackup(ctx) + if err != nil { + return err + } + return bh.Error() +} + // executeRestoreFullBackup restores the files from a full backup. The underlying mysql database service is expected to be stopped. func (be *BuiltinBackupEngine) executeRestoreFullBackup(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle, bm builtinBackupManifest) error { if err := prepareToRestore(ctx, params.Cnf, params.Mysqld, params.Logger, params.MysqlShutdownTimeout); err != nil { @@ -997,8 +1108,8 @@ func (be *BuiltinBackupEngine) executeRestoreIncrementalBackup(ctx context.Conte // we return the position from which replication should start // otherwise an error is returned func (be *BuiltinBackupEngine) ExecuteRestore(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (*BackupManifest, error) { - var bm builtinBackupManifest - if err := getBackupManifestInto(ctx, bh, &bm); err != nil { + bm, err := be.restoreManifest(ctx, params, bh) + if err != nil { return nil, err } @@ -1007,7 +1118,6 @@ func (be *BuiltinBackupEngine) ExecuteRestore(ctx context.Context, params Restor return nil, err } - var err error if bm.Incremental { err = be.executeRestoreIncrementalBackup(ctx, params, bh, bm) } else { @@ -1020,6 +1130,26 @@ func (be *BuiltinBackupEngine) ExecuteRestore(ctx context.Context, params Restor return &bm.BackupManifest, nil } +func (be *BuiltinBackupEngine) restoreManifest(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (bm builtinBackupManifest, finalErr error) { + var retryCount int + defer func() { + state := "Completed" + if finalErr != nil { + state = "Failed" + } + params.Logger.Infof("%s restoring %s %s", state, backupManifestFileName, retryToString(retryCount)) + }() + + for ; retryCount <= maxRetriesPerFile; retryCount++ { + params.Logger.Infof("Restoring file %s %s", backupManifestFileName, retryToString(retryCount)) + if finalErr = getBackupManifestInto(ctx, bh, &bm); finalErr == nil { + break + } + params.Logger.Infof("Failed restoring %s %s", backupManifestFileName, retryToString(retryCount)) + } + return +} + // restoreFiles will copy all the files from the BackupStorage to the // right place. func (be *BuiltinBackupEngine) restoreFiles(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle, bm builtinBackupManifest) (createdDir string, err error) { @@ -1040,75 +1170,79 @@ func (be *BuiltinBackupEngine) restoreFiles(ctx context.Context, params RestoreP } } fes := bm.FileEntries - sema := semaphore.NewWeighted(int64(params.Concurrency)) - rec := concurrency.AllErrorRecorder{} - wg := sync.WaitGroup{} - - ctxCancel, cancel := context.WithCancel(ctx) - defer func() { - // We may still have operations in flight that require a valid context, such as adding files to S3. - // Unless we encountered an error, we should not cancel the context. This is taken care of later - // in the process. If we encountered an error however, we can safely cancel the context as we should - // no longer work on anything and exit fast. + _ = be.restoreFileEntries(ctx, fes, bh, bm, params, createdDir) + if files := bh.GetFailedFiles(); len(files) > 0 { + newFEs := make([]FileEntry, len(fes)) + for _, file := range files { + fileNb, err := strconv.Atoi(file) + if err != nil { + return "", vterrors.Wrapf(err, "failed to retry file '%s'", file) + } + oldFes := fes[fileNb] + newFEs[fileNb] = FileEntry{ + Base: oldFes.Base, + Name: oldFes.Name, + ParentPath: oldFes.ParentPath, + Hash: oldFes.Hash, + RetryCount: 1, + } + bh.ResetErrorForFile(file) + } + err = be.restoreFileEntries(ctx, newFEs, bh, bm, params, createdDir) if err != nil { - cancel() + return "", err } - }() + } + return createdDir, nil +} + +func (be *BuiltinBackupEngine) restoreFileEntries(ctx context.Context, fes []FileEntry, bh backupstorage.BackupHandle, bm builtinBackupManifest, params RestoreParams, createdDir string) error { + g, ctx := errgroup.WithContext(ctx) + g.SetLimit(params.Concurrency) for i := range fes { - wg.Add(1) - go func(i int) { - defer wg.Done() + if fes[i].Name == "" { + continue + } + g.Go(func() error { fe := &fes[i] - // Wait until we are ready to go, return if we encounter an error - acqErr := sema.Acquire(ctxCancel, 1) - if acqErr != nil { - log.Errorf("Unable to acquire semaphore needed to restore file: %s, err: %s", fe.Name, acqErr.Error()) - rec.RecordError(acqErr) - cancel() - return - } - defer sema.Release(1) - - // First check if we have any error, if we have, there is no point trying to restore this file. - // We check for errors before checking if the context is canceled on purpose, if there was an - // error, the context would have been canceled already. - if rec.HasErrors() { - params.Logger.Errorf("Failed to restore files due to error: %v", bh.Error()) - return - } - + name := fmt.Sprintf("%v", i) // Check for context cancellation explicitly because, the way semaphore code is written, theoretically we might // end up not throwing an error even after cancellation. Please see https://cs.opensource.google/go/x/sync/+/refs/tags/v0.1.0:semaphore/semaphore.go;l=66, // which suggests that if the context is already done, `Acquire()` may still succeed without blocking. This introduces // unpredictability in my test cases, so in order to avoid that, I am adding this cancellation check. select { - case <-ctxCancel.Done(): + case <-ctx.Done(): log.Errorf("Context canceled or timed out during %q restore", fe.Name) - rec.RecordError(vterrors.Errorf(vtrpc.Code_CANCELED, "context canceled")) - return + bh.RecordError(name, vterrors.Errorf(vtrpc.Code_CANCELED, "context canceled")) + return nil default: } fe.ParentPath = createdDir + // And restore the file. - name := fmt.Sprintf("%v", i) - params.Logger.Infof("Copying file %v: %v", name, fe.Name) - err := be.restoreFile(ctxCancel, params, bh, fe, bm, name) - if err != nil { - rec.RecordError(vterrors.Wrapf(err, "can't restore file %v to %v", name, fe.Name)) - cancel() + params.Logger.Infof("Copying file %v: %v %s", name, fe.Name, retryToString(fe.RetryCount)) + if errRestore := be.restoreFile(ctx, params, bh, fe, bm, name); errRestore != nil { + bh.RecordError(name, vterrors.Wrapf(errRestore, "failed to restore file %v to %v", name, fe.Name)) + if fe.RetryCount >= maxRetriesPerFile { + // this is the last attempt, and we have an error, we can return an error, which will let errgroup + // know it can cancel the context + return errRestore + } } - }(i) + return nil + }) } - wg.Wait() - return createdDir, rec.Error() + _ = g.Wait() + return bh.Error() } // restoreFile restores an individual file. func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle, fe *FileEntry, bm builtinBackupManifest, name string) (finalErr error) { ctx, cancel := context.WithCancel(ctx) defer cancel() + // Open the source file for reading. openSourceAt := time.Now() source, err := bh.ReadFile(ctx, name) @@ -1126,8 +1260,15 @@ func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, params RestorePa params.Stats.Scope(stats.Operation("Source:Close")).TimedIncrement(time.Since(closeSourceAt)) }() - br := newBackupReader(name, 0, timedSource) - go br.ReportProgress(ctx, builtinBackupProgress, params.Logger, true) + // Create the backup/source reader and start reporting progress + retryStr := retryToString(fe.RetryCount) + br := newBackupReader(fe.Name, 0, timedSource) + go br.ReportProgress(ctx, builtinBackupProgress, params.Logger, true, retryStr) + defer func() { + if err := br.Close(finalErr == nil); err != nil { + finalErr = vterrors.Wrap(finalErr, "failed to close the source reader") + } + }() var reader io.Reader = br // Open the destination file for writing. @@ -1213,10 +1354,6 @@ func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, params RestorePa return vterrors.Wrap(err, "failed to flush destination buffer") } - if err := br.Close(); err != nil { - return vterrors.Wrap(err, "failed to close the source reader") - } - return nil } diff --git a/go/vt/mysqlctl/cephbackupstorage/ceph.go b/go/vt/mysqlctl/cephbackupstorage/ceph.go index f8e33dbe641..62330b869f0 100644 --- a/go/vt/mysqlctl/cephbackupstorage/ceph.go +++ b/go/vt/mysqlctl/cephbackupstorage/ceph.go @@ -32,9 +32,10 @@ import ( minio "github.com/minio/minio-go" "github.com/spf13/pflag" - "vitess.io/vitess/go/vt/concurrency" - "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" + + "vitess.io/vitess/go/vt/log" + errorsbackup "vitess.io/vitess/go/vt/mysqlctl/errors" "vitess.io/vitess/go/vt/servenv" ) @@ -69,23 +70,8 @@ type CephBackupHandle struct { dir string name string readOnly bool - errors concurrency.AllErrorRecorder waitGroup sync.WaitGroup -} - -// RecordError is part of the concurrency.ErrorRecorder interface. -func (bh *CephBackupHandle) RecordError(err error) { - bh.errors.RecordError(err) -} - -// HasErrors is part of the concurrency.ErrorRecorder interface. -func (bh *CephBackupHandle) HasErrors() bool { - return bh.errors.HasErrors() -} - -// Error is part of the concurrency.ErrorRecorder interface. -func (bh *CephBackupHandle) Error() error { - return bh.errors.Error() + errorsbackup.PerFileErrorRecorder } // Directory implements BackupHandle. @@ -109,7 +95,7 @@ func (bh *CephBackupHandle) AddFile(ctx context.Context, filename string, filesi defer bh.waitGroup.Done() // ceph bucket name is where the backups will go - //backup handle dir field contains keyspace/shard value + // backup handle dir field contains keyspace/shard value bucket := alterBucketName(bh.dir) // Give PutObject() the read end of the pipe. @@ -120,7 +106,7 @@ func (bh *CephBackupHandle) AddFile(ctx context.Context, filename string, filesi // Signal the writer that an error occurred, in case it's not done writing yet. reader.CloseWithError(err) // In case the error happened after the writer finished, we need to remember it. - bh.RecordError(err) + bh.RecordError(filename, err) } }() // Give our caller the write end of the pipe. diff --git a/go/vt/mysqlctl/errors/errors.go b/go/vt/mysqlctl/errors/errors.go new file mode 100644 index 00000000000..02485901e50 --- /dev/null +++ b/go/vt/mysqlctl/errors/errors.go @@ -0,0 +1,106 @@ +/* +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 errors + +import ( + "errors" + "strings" + "sync" +) + +type BackupErrorRecorder interface { + RecordError(string, error) + HasErrors() bool + Error() error + GetFailedFiles() []string + ResetErrorForFile(string) +} + +// PerFileErrorRecorder records errors and group them by filename. +// This is particularly useful when processing several files at the same time +// and wanting to know which files failed. +type PerFileErrorRecorder struct { + mu sync.Mutex + errors map[string][]error +} + +// RecordError records a possible error: +// - does nothing if err is nil +func (pfer *PerFileErrorRecorder) RecordError(filename string, err error) { + if err == nil { + return + } + + pfer.mu.Lock() + defer pfer.mu.Unlock() + + if pfer.errors == nil { + pfer.errors = make(map[string][]error, 1) + } + pfer.errors[filename] = append(pfer.errors[filename], err) +} + +// HasErrors returns true if we ever recorded an error +func (pfer *PerFileErrorRecorder) HasErrors() bool { + pfer.mu.Lock() + defer pfer.mu.Unlock() + return len(pfer.errors) > 0 +} + +// Error returns all the errors that were recorded +func (pfer *PerFileErrorRecorder) Error() error { + pfer.mu.Lock() + defer pfer.mu.Unlock() + if pfer.errors == nil { + return nil + } + + var errs []string + for _, fileErrs := range pfer.errors { + for _, err := range fileErrs { + errs = append(errs, err.Error()) + } + } + if len(errs) == 0 { + return nil + } + return errors.New(strings.Join(errs, "; ")) +} + +// GetFailedFiles returns a slice of filenames, each of this file have at least 1 error. +func (pfer *PerFileErrorRecorder) GetFailedFiles() []string { + pfer.mu.Lock() + defer pfer.mu.Unlock() + if pfer.errors == nil { + return nil + } + files := make([]string, 0, len(pfer.errors)) + for filename := range pfer.errors { + files = append(files, filename) + } + return files +} + +// ResetErrorForFile removes all the errors of a given file. +func (pfer *PerFileErrorRecorder) ResetErrorForFile(filename string) { + pfer.mu.Lock() + defer pfer.mu.Unlock() + if pfer.errors == nil { + return + } + delete(pfer.errors, filename) +} diff --git a/go/vt/mysqlctl/fakebackupstorage.go b/go/vt/mysqlctl/fakebackupstorage.go index 75587191157..582b422cf58 100644 --- a/go/vt/mysqlctl/fakebackupstorage.go +++ b/go/vt/mysqlctl/fakebackupstorage.go @@ -21,20 +21,21 @@ import ( "fmt" "io" - "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" + "vitess.io/vitess/go/vt/mysqlctl/errors" ) type FakeBackupHandle struct { Dir string NameV string ReadOnly bool - Errors concurrency.AllErrorRecorder + errors.PerFileErrorRecorder AbortBackupCalls []context.Context AbortBackupReturn error AddFileCalls []FakeBackupHandleAddFileCall AddFileReturn FakeBackupHandleAddFileReturn + AddFileReturnF func(filename string) FakeBackupHandleAddFileReturn EndBackupCalls []context.Context EndBackupReturn error ReadFileCalls []FakeBackupHandleReadFileCall @@ -57,18 +58,6 @@ type FakeBackupHandleReadFileCall struct { Filename string } -func (fbh *FakeBackupHandle) RecordError(err error) { - fbh.Errors.RecordError(err) -} - -func (fbh *FakeBackupHandle) HasErrors() bool { - return fbh.Errors.HasErrors() -} - -func (fbh *FakeBackupHandle) Error() error { - return fbh.Errors.Error() -} - func (fbh *FakeBackupHandle) Directory() string { return fbh.Dir } @@ -79,6 +68,11 @@ func (fbh *FakeBackupHandle) Name() string { func (fbh *FakeBackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { fbh.AddFileCalls = append(fbh.AddFileCalls, FakeBackupHandleAddFileCall{ctx, filename, filesize}) + + if fbh.AddFileReturnF != nil { + r := fbh.AddFileReturnF(filename) + return r.WriteCloser, r.Err + } return fbh.AddFileReturn.WriteCloser, fbh.AddFileReturn.Err } diff --git a/go/vt/mysqlctl/filebackupstorage/file.go b/go/vt/mysqlctl/filebackupstorage/file.go index 99148d9169b..bd73c55e70c 100644 --- a/go/vt/mysqlctl/filebackupstorage/file.go +++ b/go/vt/mysqlctl/filebackupstorage/file.go @@ -27,8 +27,9 @@ import ( "github.com/spf13/pflag" + "vitess.io/vitess/go/vt/mysqlctl/errors" + "vitess.io/vitess/go/ioutil" - "vitess.io/vitess/go/vt/concurrency" stats "vitess.io/vitess/go/vt/mysqlctl/backupstats" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/servenv" @@ -59,7 +60,7 @@ type FileBackupHandle struct { dir string name string readOnly bool - errors concurrency.AllErrorRecorder + errors.PerFileErrorRecorder } func NewBackupHandle( @@ -79,21 +80,6 @@ func NewBackupHandle( } } -// RecordError is part of the concurrency.ErrorRecorder interface. -func (fbh *FileBackupHandle) RecordError(err error) { - fbh.errors.RecordError(err) -} - -// HasErrors is part of the concurrency.ErrorRecorder interface. -func (fbh *FileBackupHandle) HasErrors() bool { - return fbh.errors.HasErrors() -} - -// Error is part of the concurrency.ErrorRecorder interface. -func (fbh *FileBackupHandle) Error() error { - return fbh.errors.Error() -} - // Directory is part of the BackupHandle interface func (fbh *FileBackupHandle) Directory() string { return fbh.dir diff --git a/go/vt/mysqlctl/gcsbackupstorage/gcs.go b/go/vt/mysqlctl/gcsbackupstorage/gcs.go index 814395a225a..adecbb9bbba 100644 --- a/go/vt/mysqlctl/gcsbackupstorage/gcs.go +++ b/go/vt/mysqlctl/gcsbackupstorage/gcs.go @@ -32,8 +32,9 @@ import ( "google.golang.org/api/iterator" "google.golang.org/api/option" + "vitess.io/vitess/go/vt/mysqlctl/errors" + "vitess.io/vitess/go/trace" - "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/servenv" ) @@ -65,22 +66,7 @@ type GCSBackupHandle struct { dir string name string readOnly bool - errors concurrency.AllErrorRecorder -} - -// RecordError is part of the concurrency.ErrorRecorder interface. -func (bh *GCSBackupHandle) RecordError(err error) { - bh.errors.RecordError(err) -} - -// HasErrors is part of the concurrency.ErrorRecorder interface. -func (bh *GCSBackupHandle) HasErrors() bool { - return bh.errors.HasErrors() -} - -// Error is part of the concurrency.ErrorRecorder interface. -func (bh *GCSBackupHandle) Error() error { - return bh.errors.Error() + errors.PerFileErrorRecorder } // Directory implements BackupHandle. diff --git a/go/vt/mysqlctl/mysqlshellbackupengine.go b/go/vt/mysqlctl/mysqlshellbackupengine.go index b7405ce7eaa..681e62d10cd 100644 --- a/go/vt/mysqlctl/mysqlshellbackupengine.go +++ b/go/vt/mysqlctl/mysqlshellbackupengine.go @@ -56,8 +56,6 @@ var ( // disable redo logging and double write buffer mysqlShellSpeedUpRestore = false - mysqlShellBackupBinaryName = "mysqlsh" - // use when checking if we need to create the directory on the local filesystem or not. knownObjectStoreParams = []string{"s3BucketName", "osBucketName", "azureContainerName"} @@ -87,7 +85,9 @@ type MySQLShellBackupManifest struct { } func init() { - BackupRestoreEngineMap[mysqlShellBackupEngineName] = &MySQLShellBackupEngine{} + BackupRestoreEngineMap[mysqlShellBackupEngineName] = &MySQLShellBackupEngine{ + binaryName: "mysqlsh", + } for _, cmd := range []string{"vtcombo", "vttablet", "vtbackup", "vttestserver", "vtctldclient"} { servenv.OnParseFor(cmd, registerMysqlShellBackupEngineFlags) @@ -106,6 +106,7 @@ func registerMysqlShellBackupEngineFlags(fs *pflag.FlagSet) { // MySQLShellBackupEngine encapsulates the logic to implement the restoration // of a mysql-shell based backup. type MySQLShellBackupEngine struct { + binaryName string } const ( @@ -164,41 +165,37 @@ func (be *MySQLShellBackupEngine) ExecuteBackup(ctx context.Context, params Back return BackupUnusable, vterrors.Wrap(err, "failed to fetch position") } - cmd := exec.CommandContext(ctx, mysqlShellBackupBinaryName, args...) + cmd := exec.CommandContext(ctx, be.binaryName, args...) params.Logger.Infof("running %s", cmd.String()) - cmdOut, err := cmd.StdoutPipe() - if err != nil { - return BackupUnusable, vterrors.Wrap(err, "cannot create stdout pipe") - } - cmdOriginalErr, err := cmd.StderrPipe() - if err != nil { - return BackupUnusable, vterrors.Wrap(err, "cannot create stderr pipe") - } - if err := cmd.Start(); err != nil { - return BackupUnusable, vterrors.Wrap(err, "can't start mysqlshell") - } + stdoutReader, stdoutWriter := io.Pipe() + stderrReader, stderrWriter := io.Pipe() + lockWaiterReader, lockWaiterWriter := io.Pipe() - pipeReader, pipeWriter := io.Pipe() - cmdErr := io.TeeReader(cmdOriginalErr, pipeWriter) + cmd.Stdout = stdoutWriter + cmd.Stderr = stderrWriter + combinedErr := io.TeeReader(stderrReader, lockWaiterWriter) cmdWg := &sync.WaitGroup{} cmdWg.Add(3) - go releaseReadLock(ctx, pipeReader, params, cmdWg, lockAcquired) - go scanLinesToLogger(mysqlShellBackupEngineName+" stdout", cmdOut, params.Logger, cmdWg.Done) - go scanLinesToLogger(mysqlShellBackupEngineName+" stderr", cmdErr, params.Logger, cmdWg.Done) + go releaseReadLock(ctx, lockWaiterReader, params, cmdWg, lockAcquired) + go scanLinesToLogger(mysqlShellBackupEngineName+" stdout", stdoutReader, params.Logger, cmdWg.Done) + go scanLinesToLogger(mysqlShellBackupEngineName+" stderr", combinedErr, params.Logger, cmdWg.Done) - // Get exit status. - if err := cmd.Wait(); err != nil { - pipeWriter.Close() // make sure we close the writer so the goroutines above will complete. - return BackupUnusable, vterrors.Wrap(err, mysqlShellBackupEngineName+" failed") - } + // we run the command, wait for it to complete and close all pipes so the goroutines can complete on their own. + // after that we can process if an error has happened or not. + err = cmd.Run() - // close the pipeWriter and wait for the goroutines to have read all the logs - pipeWriter.Close() + stdoutWriter.Close() + stderrWriter.Close() + lockWaiterWriter.Close() cmdWg.Wait() + if err != nil { + return BackupUnusable, vterrors.Wrap(err, mysqlShellBackupEngineName+" failed") + } + // open the MANIFEST params.Logger.Infof("Writing backup MANIFEST") mwc, err := bh.AddFile(ctx, backupManifestFileName, backupstorage.FileSizeUnknown) @@ -371,7 +368,7 @@ func (be *MySQLShellBackupEngine) ExecuteRestore(ctx context.Context, params Res if err := cmd.Wait(); err != nil { return nil, vterrors.Wrap(err, mysqlShellBackupEngineName+" failed") } - params.Logger.Infof("%s completed successfully", mysqlShellBackupBinaryName) + params.Logger.Infof("%s completed successfully", be.binaryName) // disable local_infile now that the restore is done. err = params.Mysqld.ExecuteSuperQuery(ctx, "SET GLOBAL LOCAL_INFILE=0") diff --git a/go/vt/mysqlctl/mysqlshellbackupengine_test.go b/go/vt/mysqlctl/mysqlshellbackupengine_test.go index 67f27b5382e..80491ec2afc 100644 --- a/go/vt/mysqlctl/mysqlshellbackupengine_test.go +++ b/go/vt/mysqlctl/mysqlshellbackupengine_test.go @@ -325,13 +325,10 @@ func generateTestFile(t *testing.T, name, contents string) { // during ExecuteBackup(), even if the backup didn't succeed. func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { originalLocation := mysqlShellBackupLocation - originalBinary := mysqlShellBackupBinaryName mysqlShellBackupLocation = "logical" - mysqlShellBackupBinaryName = path.Join(t.TempDir(), "test.sh") - defer func() { // restore the original values. + defer func() { // restore the original value. mysqlShellBackupLocation = originalLocation - mysqlShellBackupBinaryName = originalBinary }() logger := logutil.NewMemoryLogger() @@ -340,7 +337,6 @@ func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { mysql := NewFakeMysqlDaemon(fakedb) defer mysql.Close() - be := &MySQLShellBackupEngine{} params := BackupParams{ TabletAlias: "test", Logger: logger, @@ -351,6 +347,7 @@ func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { } t.Run("lock released if we see the mysqlsh lock being acquired", func(t *testing.T) { + be := &MySQLShellBackupEngine{binaryName: path.Join(t.TempDir(), "mysqlsh.sh")} logger.Clear() manifestBuffer := ioutil.NewBytesBufferWriter() bs.StartBackupReturn.BackupHandle = &FakeBackupHandle{ @@ -359,7 +356,8 @@ func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { } // this simulates mysql shell completing without any issues. - generateTestFile(t, mysqlShellBackupBinaryName, fmt.Sprintf("#!/bin/bash\n>&2 echo %s", mysqlShellLockMessage)) + generateTestFile(t, be.binaryName, fmt.Sprintf( + "#!/bin/bash\n>&2 echo %s; echo \"backup completed\"; sleep 0.01", mysqlShellLockMessage)) bh, err := bs.StartBackup(context.Background(), t.TempDir(), t.Name()) require.NoError(t, err) @@ -380,7 +378,8 @@ func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { "failed to release the global lock after mysqlsh") }) - t.Run("lock released if when we don't see mysqlsh released it", func(t *testing.T) { + t.Run("lock released if we don't see mysqlsh release it", func(t *testing.T) { + be := &MySQLShellBackupEngine{binaryName: path.Join(t.TempDir(), "mysqlsh.sh")} mysql.GlobalReadLock = false // clear lock status. logger.Clear() manifestBuffer := ioutil.NewBytesBufferWriter() @@ -390,7 +389,7 @@ func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { } // this simulates mysqlshell completing, but we don't see the message that is released its lock. - generateTestFile(t, mysqlShellBackupBinaryName, "#!/bin/bash\nexit 0") + generateTestFile(t, be.binaryName, "#!/bin/bash\nexit 0") bh, err := bs.StartBackup(context.Background(), t.TempDir(), t.Name()) require.NoError(t, err) @@ -407,6 +406,7 @@ func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { }) t.Run("lock released when backup fails", func(t *testing.T) { + be := &MySQLShellBackupEngine{binaryName: path.Join(t.TempDir(), "mysqlsh.sh")} mysql.GlobalReadLock = false // clear lock status. logger.Clear() manifestBuffer := ioutil.NewBytesBufferWriter() @@ -416,7 +416,7 @@ func TestMySQLShellBackupEngine_ExecuteBackup_ReleaseLock(t *testing.T) { } // this simulates the backup process failing. - generateTestFile(t, mysqlShellBackupBinaryName, "#!/bin/bash\nexit 1") + generateTestFile(t, be.binaryName, "#!/bin/bash\nexit 1") bh, err := bs.StartBackup(context.Background(), t.TempDir(), t.Name()) require.NoError(t, err) diff --git a/go/vt/mysqlctl/s3backupstorage/s3.go b/go/vt/mysqlctl/s3backupstorage/s3.go index b3a8117aafa..4dd583009aa 100644 --- a/go/vt/mysqlctl/s3backupstorage/s3.go +++ b/go/vt/mysqlctl/s3backupstorage/s3.go @@ -40,21 +40,29 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/retry" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" transport "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/dustin/go-humanize" "github.com/spf13/pflag" - "vitess.io/vitess/go/vt/concurrency" + errorsbackup "vitess.io/vitess/go/vt/mysqlctl/errors" + "vitess.io/vitess/go/vt/log" stats "vitess.io/vitess/go/vt/mysqlctl/backupstats" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/servenv" ) +const ( + sseCustomerPrefix = "sse_c:" + MaxPartSize = 1024 * 1024 * 1024 * 5 // 5GiB - limited by AWS https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html +) + var ( // AWS API region region string @@ -84,6 +92,11 @@ var ( // path component delimiter delimiter = "/" + + // minimum part size + minPartSize int64 + + ErrPartSize = errors.New("minimum S3 part size must be between 5MiB and 5GiB") ) func registerFlags(fs *pflag.FlagSet) { @@ -96,6 +109,7 @@ func registerFlags(fs *pflag.FlagSet) { fs.BoolVar(&tlsSkipVerifyCert, "s3_backup_tls_skip_verify_cert", false, "skip the 'certificate is valid' check for SSL connections.") fs.StringVar(&requiredLogLevel, "s3_backup_log_level", "LogOff", "determine the S3 loglevel to use from LogOff, LogDebug, LogDebugWithSigning, LogDebugWithHTTPBody, LogDebugWithRequestRetries, LogDebugWithRequestErrors.") fs.StringVar(&sse, "s3_backup_server_side_encryption", "", "server-side encryption algorithm (e.g., AES256, aws:kms, sse_c:/path/to/key/file).") + fs.Int64Var(&minPartSize, "s3_backup_aws_min_partsize", manager.MinUploadPartSize, "Minimum part size to use, defaults to 5MiB but can be increased due to the dataset size.") } func init() { @@ -109,8 +123,6 @@ type logNameToLogLevel map[string]aws.ClientLogMode var logNameMap logNameToLogLevel -const sseCustomerPrefix = "sse_c:" - type endpointResolver struct { r s3.EndpointResolverV2 endpoint *string @@ -144,8 +156,8 @@ type S3BackupHandle struct { dir string name string readOnly bool - errors concurrency.AllErrorRecorder waitGroup sync.WaitGroup + errorsbackup.PerFileErrorRecorder } // Directory is part of the backupstorage.BackupHandle interface. @@ -158,39 +170,28 @@ func (bh *S3BackupHandle) Name() string { return bh.name } -// RecordError is part of the concurrency.ErrorRecorder interface. -func (bh *S3BackupHandle) RecordError(err error) { - bh.errors.RecordError(err) -} - -// HasErrors is part of the concurrency.ErrorRecorder interface. -func (bh *S3BackupHandle) HasErrors() bool { - return bh.errors.HasErrors() -} - -// Error is part of the concurrency.ErrorRecorder interface. -func (bh *S3BackupHandle) Error() error { - return bh.errors.Error() -} - // AddFile is part of the backupstorage.BackupHandle interface. func (bh *S3BackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { if bh.readOnly { return nil, fmt.Errorf("AddFile cannot be called on read-only backup") } - // Calculate s3 upload part size using the source filesize - partSizeBytes := manager.DefaultUploadPartSize - if filesize > 0 { - minimumPartSize := float64(filesize) / float64(manager.MaxUploadParts) - // Round up to ensure large enough partsize - calculatedPartSizeBytes := int64(math.Ceil(minimumPartSize)) - if calculatedPartSizeBytes > partSizeBytes { - partSizeBytes = calculatedPartSizeBytes - } + partSizeBytes, err := calculateUploadPartSize(filesize) + if err != nil { + return nil, err } + bh.bs.params.Logger.Infof("Using S3 upload part size: %s", humanize.IBytes(uint64(partSizeBytes))) + reader, writer := io.Pipe() + bh.handleAddFile(ctx, filename, partSizeBytes, reader, func(err error) { + reader.CloseWithError(err) + }) + + return writer, nil +} + +func (bh *S3BackupHandle) handleAddFile(ctx context.Context, filename string, partSizeBytes int64, reader io.Reader, closer func(error)) { bh.waitGroup.Add(1) go func() { @@ -221,12 +222,36 @@ func (bh *S3BackupHandle) AddFile(ctx context.Context, filename string, filesize }) }) if err != nil { - reader.CloseWithError(err) - bh.RecordError(err) + closer(err) + bh.RecordError(filename, err) } }() +} - return writer, nil +// calculateUploadPartSize is a helper to calculate the part size, taking into consideration the minimum part size +// passed in by an operator. +func calculateUploadPartSize(filesize int64) (partSizeBytes int64, err error) { + // Calculate s3 upload part size using the source filesize + partSizeBytes = manager.DefaultUploadPartSize + if filesize > 0 { + minimumPartSize := float64(filesize) / float64(manager.MaxUploadParts) + // Round up to ensure large enough partsize + calculatedPartSizeBytes := int64(math.Ceil(minimumPartSize)) + if calculatedPartSizeBytes > partSizeBytes { + partSizeBytes = calculatedPartSizeBytes + } + } + + if minPartSize != 0 && partSizeBytes < minPartSize { + if minPartSize > MaxPartSize || minPartSize < manager.MinUploadPartSize { // 5GiB and 5MiB respectively + return 0, fmt.Errorf("%w, currently set to %s", + ErrPartSize, humanize.IBytes(uint64(minPartSize)), + ) + } + partSizeBytes = int64(minPartSize) + } + + return } // EndBackup is part of the backupstorage.BackupHandle interface. @@ -505,13 +530,24 @@ func (bs *S3BackupStorage) client() (*s3.Client, error) { return nil, err } - bs._client = s3.NewFromConfig(cfg, func(o *s3.Options) { - o.UsePathStyle = forcePath - if retryCount >= 0 { - o.RetryMaxAttempts = retryCount - o.Retryer = &ClosedConnectionRetryer{} - } - }, s3.WithEndpointResolverV2(newEndpointResolver())) + options := []func(options *s3.Options){ + func(o *s3.Options) { + o.UsePathStyle = forcePath + if retryCount >= 0 { + o.RetryMaxAttempts = retryCount + o.Retryer = &ClosedConnectionRetryer{ + awsRetryer: retry.NewStandard(func(options *retry.StandardOptions) { + options.MaxAttempts = retryCount + }), + } + } + }, + } + if endpoint != "" { + options = append(options, s3.WithEndpointResolverV2(newEndpointResolver())) + } + + bs._client = s3.NewFromConfig(cfg, options...) if len(bucket) == 0 { return nil, fmt.Errorf("--s3_backup_storage_bucket required") diff --git a/go/vt/mysqlctl/s3backupstorage/s3_mock.go b/go/vt/mysqlctl/s3backupstorage/s3_mock.go new file mode 100644 index 00000000000..910a22bd9d5 --- /dev/null +++ b/go/vt/mysqlctl/s3backupstorage/s3_mock.go @@ -0,0 +1,231 @@ +/* +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 s3backupstorage + +import ( + "context" + "errors" + "fmt" + "io" + "sync" + + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl/backupstats" + "vitess.io/vitess/go/vt/mysqlctl/backupstorage" +) + +type FakeS3BackupHandle struct { + *S3BackupHandle + + AddFileReturnF func(s3 *S3BackupHandle, ctx context.Context, filename string, filesize int64, firstAdd bool) (io.WriteCloser, error) + ReadFileReturnF func(s3 *S3BackupHandle, ctx context.Context, filename string, firstRead bool) (io.ReadCloser, error) + + mu sync.Mutex + addPerFile map[string]int + readPerFile map[string]int +} + +type FakeConfig struct { + Region string + Endpoint string + Bucket string + ForcePath bool +} + +func InitFlag(cfg FakeConfig) { + region = cfg.Region + endpoint = cfg.Endpoint + bucket = cfg.Bucket + forcePath = cfg.ForcePath +} + +func NewFakeS3BackupHandle(ctx context.Context, dir, name string, logger logutil.Logger, stats backupstats.Stats) (*FakeS3BackupHandle, error) { + s := newS3BackupStorage() + bs := s.WithParams(backupstorage.Params{ + Logger: logger, + Stats: stats, + }) + bh, err := bs.StartBackup(ctx, dir, name) + if err != nil { + return nil, err + } + return &FakeS3BackupHandle{ + S3BackupHandle: bh.(*S3BackupHandle), + addPerFile: make(map[string]int), + readPerFile: make(map[string]int), + }, nil +} + +func NewFakeS3RestoreHandle(ctx context.Context, dir string, logger logutil.Logger, stats backupstats.Stats) (*FakeS3BackupHandle, error) { + s := newS3BackupStorage() + bs := s.WithParams(backupstorage.Params{ + Logger: logger, + Stats: stats, + }) + bhs, err := bs.ListBackups(ctx, dir) + if err != nil { + return nil, err + } + return &FakeS3BackupHandle{ + S3BackupHandle: bhs[0].(*S3BackupHandle), + addPerFile: make(map[string]int), + readPerFile: make(map[string]int), + }, nil +} + +func (fbh *FakeS3BackupHandle) Directory() string { + return fbh.S3BackupHandle.Directory() +} + +func (fbh *FakeS3BackupHandle) Name() string { + return fbh.S3BackupHandle.Name() +} + +func (fbh *FakeS3BackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { + fbh.mu.Lock() + defer func() { + fbh.addPerFile[filename] += 1 + fbh.mu.Unlock() + }() + + if fbh.AddFileReturnF != nil { + return fbh.AddFileReturnF(fbh.S3BackupHandle, ctx, filename, filesize, fbh.addPerFile[filename] == 0) + } + return fbh.S3BackupHandle.AddFile(ctx, filename, filesize) +} + +func (fbh *FakeS3BackupHandle) EndBackup(ctx context.Context) error { + return fbh.S3BackupHandle.EndBackup(ctx) +} + +func (fbh *FakeS3BackupHandle) AbortBackup(ctx context.Context) error { + return fbh.S3BackupHandle.AbortBackup(ctx) +} + +func (fbh *FakeS3BackupHandle) ReadFile(ctx context.Context, filename string) (io.ReadCloser, error) { + fbh.mu.Lock() + defer func() { + fbh.readPerFile[filename] += 1 + fbh.mu.Unlock() + }() + + if fbh.ReadFileReturnF != nil { + return fbh.ReadFileReturnF(fbh.S3BackupHandle, ctx, filename, fbh.readPerFile[filename] == 0) + } + return fbh.S3BackupHandle.ReadFile(ctx, filename) +} + +func (fbh *FakeS3BackupHandle) RecordError(s string, err error) { + fbh.S3BackupHandle.RecordError(s, err) +} + +func (fbh *FakeS3BackupHandle) HasErrors() bool { + return fbh.S3BackupHandle.HasErrors() +} + +func (fbh *FakeS3BackupHandle) Error() error { + return fbh.S3BackupHandle.Error() +} + +func (fbh *FakeS3BackupHandle) GetFailedFiles() []string { + return fbh.S3BackupHandle.GetFailedFiles() +} + +func (fbh *FakeS3BackupHandle) ResetErrorForFile(s string) { + fbh.S3BackupHandle.ResetErrorForFile(s) +} + +type failReadPipeReader struct { + *io.PipeReader +} + +func (fwr *failReadPipeReader) Read(p []byte) (n int, err error) { + return 0, errors.New("failing read") +} + +func FailFirstWrite(s3bh *S3BackupHandle, ctx context.Context, filename string, filesize int64, firstAdd bool) (io.WriteCloser, error) { + if s3bh.readOnly { + return nil, fmt.Errorf("AddFile cannot be called on read-only backup") + } + + partSizeBytes, err := calculateUploadPartSize(filesize) + if err != nil { + return nil, err + } + + reader, writer := io.Pipe() + r := io.Reader(reader) + + if firstAdd { + r = &failReadPipeReader{PipeReader: reader} + } + + s3bh.handleAddFile(ctx, filename, partSizeBytes, r, func(err error) { + reader.CloseWithError(err) + }) + return writer, nil +} + +func FailAllWrites(s3bh *S3BackupHandle, ctx context.Context, filename string, filesize int64, _ bool) (io.WriteCloser, error) { + if s3bh.readOnly { + return nil, fmt.Errorf("AddFile cannot be called on read-only backup") + } + + partSizeBytes, err := calculateUploadPartSize(filesize) + if err != nil { + return nil, err + } + + reader, writer := io.Pipe() + r := &failReadPipeReader{PipeReader: reader} + + s3bh.handleAddFile(ctx, filename, partSizeBytes, r, func(err error) { + r.PipeReader.CloseWithError(err) + }) + return writer, nil +} + +type failRead struct{} + +func (fr *failRead) Read(p []byte) (n int, err error) { + return 0, errors.New("failing read") +} + +func (fr *failRead) Close() error { + return nil +} + +func FailFirstRead(s3bh *S3BackupHandle, ctx context.Context, filename string, firstRead bool) (io.ReadCloser, error) { + rc, err := s3bh.ReadFile(ctx, filename) + if err != nil { + return nil, err + } + if firstRead { + return &failRead{}, nil + } + return rc, nil +} + +// FailAllReadExpectManifest is used to fail every attempt at reading a file from S3. +// Only the MANIFEST file is allowed to be read, because otherwise we wouldn't even try to read the normal files. +func FailAllReadExpectManifest(s3bh *S3BackupHandle, ctx context.Context, filename string, _ bool) (io.ReadCloser, error) { + const manifestFileName = "MANIFEST" + if filename == manifestFileName { + return s3bh.ReadFile(ctx, filename) + } + return &failRead{}, nil +} diff --git a/go/vt/mysqlctl/s3backupstorage/s3_test.go b/go/vt/mysqlctl/s3backupstorage/s3_test.go index 84ef8de6e48..5e9364219af 100644 --- a/go/vt/mysqlctl/s3backupstorage/s3_test.go +++ b/go/vt/mysqlctl/s3backupstorage/s3_test.go @@ -328,3 +328,68 @@ func TestWithParams(t *testing.T) { assert.NotNil(t, s3.transport.DialContext) assert.NotNil(t, s3.transport.Proxy) } + +func TestCalculateUploadPartSize(t *testing.T) { + originalMinimum := minPartSize + defer func() { minPartSize = originalMinimum }() + + tests := []struct { + name string + filesize int64 + minimumPartSize int64 + want int64 + err error + }{ + { + name: "minimum - 10 MiB", + filesize: 1024 * 1024 * 10, // 10 MiB + minimumPartSize: 1024 * 1024 * 5, // 5 MiB + want: 1024 * 1024 * 5, // 5 MiB, + err: nil, + }, + { + name: "below minimum - 10 MiB", + filesize: 1024 * 1024 * 10, // 10 MiB + minimumPartSize: 1024 * 1024 * 8, // 8 MiB + want: 1024 * 1024 * 8, // 8 MiB, + err: nil, + }, + { + name: "above minimum - 1 TiB", + filesize: 1024 * 1024 * 1024 * 1024, // 1 TiB + minimumPartSize: 1024 * 1024 * 5, // 5 MiB + want: 109951163, // ~104 MiB + err: nil, + }, + { + name: "below minimum - 1 TiB", + filesize: 1024 * 1024 * 1024 * 1024, // 1 TiB + minimumPartSize: 1024 * 1024 * 200, // 200 MiB + want: 1024 * 1024 * 200, // 200 MiB + err: nil, + }, + { + name: "below S3 limits - 5 MiB", + filesize: 1024 * 1024 * 3, // 3 MiB + minimumPartSize: 1024 * 1024 * 4, // 4 MiB + want: 1024 * 1024 * 5, // 5 MiB - should always return the minimum + err: nil, + }, + { + name: "above S3 limits - 5 GiB", + filesize: 1024 * 1024 * 1024 * 1024, // 1 TiB + minimumPartSize: 1024 * 1024 * 1024 * 6, // 6 GiB + want: 0, + err: ErrPartSize, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + minPartSize = tt.minimumPartSize + partSize, err := calculateUploadPartSize(tt.filesize) + require.ErrorIs(t, err, tt.err) + require.Equal(t, tt.want, partSize) + }) + } +} diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index 35e738f772e..e3523b6b384 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -1333,8 +1333,17 @@ type RowChange struct { Before *query.Row `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"` After *query.Row `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"` - // DataColumns is a bitmap of all columns: bit is set if column is present in the after image + // DataColumns is a bitmap of all columns: bit is set if column is + // present in the after image. DataColumns *RowChange_Bitmap `protobuf:"bytes,3,opt,name=data_columns,json=dataColumns,proto3" json:"data_columns,omitempty"` + // JsonPartialValues is a bitmap of any JSON columns, where the bit + // is set if the value in the AFTER image is a partial JSON value + // that is represented as an expression of + // JSON_[INSERT|REPLACE|REMOVE](%s, '$.path', value) which then is + // used to add/update/remove a path in the JSON document. When the + // value is used the fmt directive must be replaced by the actual + // column name of the JSON field. + JsonPartialValues *RowChange_Bitmap `protobuf:"bytes,4,opt,name=json_partial_values,json=jsonPartialValues,proto3" json:"json_partial_values,omitempty"` } func (x *RowChange) Reset() { @@ -1388,6 +1397,13 @@ func (x *RowChange) GetDataColumns() *RowChange_Bitmap { return nil } +func (x *RowChange) GetJsonPartialValues() *RowChange_Bitmap { + if x != nil { + return x.JsonPartialValues + } + return nil +} + // RowEvent represent row events for one table. type RowEvent struct { state protoimpl.MessageState @@ -3223,7 +3239,7 @@ var file_binlogdata_proto_rawDesc = []byte{ 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x22, - 0xc6, 0x01, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x22, 0x0a, + 0x94, 0x02, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, @@ -3232,313 +3248,318 @@ var file_binlogdata_proto_rawDesc = []byte{ 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x73, 0x1a, 0x32, 0x0a, 0x06, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x04, 0x63, 0x6f, 0x6c, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x08, 0x52, 0x6f, 0x77, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, - 0x6c, 0x61, 0x67, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0f, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x22, 0xe4, 0x01, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, - 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x73, - 0x65, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, 0x6e, 0x75, 0x6d, 0x53, 0x65, 0x74, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, - 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x47, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0a, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, - 0x4b, 0x73, 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, - 0x69, 0x64, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, 0x6f, 0x75, 0x72, 0x6e, - 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, - 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, - 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x70, - 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x0c, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x07, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xb6, 0x04, 0x0a, 0x06, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, + 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x13, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, + 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x52, + 0x11, 0x6a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x1a, 0x32, 0x0a, 0x06, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x63, 0x6f, 0x6c, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, + 0x72, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, + 0x67, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, + 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xe4, + 0x01, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x73, 0x65, 0x74, + 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x19, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, 0x6e, 0x75, 0x6d, 0x53, 0x65, 0x74, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x73, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1a, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, + 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x4b, 0x73, + 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, + 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, + 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x73, 0x22, 0xb6, 0x04, 0x0a, 0x06, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x72, 0x6f, + 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, + 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x12, + 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x6f, + 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x10, + 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6d, 0x6c, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x5f, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, + 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x64, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x8d, 0x01, 0x0a, + 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, + 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, 0x6b, 0x5f, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x70, 0x4b, + 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0e, 0x70, 0x5f, 0x6b, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x70, 0x4b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x41, 0x0a, 0x0d, + 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, + 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, + 0xd9, 0x01, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x10, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfd, 0x02, 0x0a, 0x0e, + 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, + 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, + 0x73, 0x74, 0x50, 0x4b, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3d, 0x0a, 0x0f, 0x56, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, + 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1c, - 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x09, - 0x72, 0x6f, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x37, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x67, 0x74, 0x69, - 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, 0x76, 0x67, 0x74, 0x69, - 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, - 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, - 0x6d, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, - 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, - 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, - 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x8d, - 0x01, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, 0x6b, - 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, - 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0e, 0x70, 0x5f, 0x6b, - 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x70, 0x4b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x41, - 0x0a, 0x0d, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, - 0x30, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x6e, - 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x5a, 0x0a, - 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, - 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfd, 0x02, - 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, - 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, + 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xbb, 0x02, 0x0a, 0x12, 0x56, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, + 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, + 0x70, 0x6b, 0x12, 0x34, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa4, 0x02, 0x0a, 0x13, 0x56, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, + 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, + 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, + 0x65, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, + 0x62, 0x65, 0x61, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x64, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, + 0xfb, 0x01, 0x0a, 0x14, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, + 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, + 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3d, 0x0a, - 0x0f, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xbb, 0x02, 0x0a, - 0x12, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, - 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, - 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, - 0x73, 0x74, 0x70, 0x6b, 0x12, 0x34, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa4, 0x02, 0x0a, 0x13, 0x56, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xde, 0x01, + 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, + 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, + 0x77, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, + 0x73, 0x74, 0x70, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0x69, + 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, + 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x58, 0x0a, 0x0b, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, + 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, + 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, + 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, - 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, - 0x6f, 0x77, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x72, - 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x68, 0x65, 0x61, - 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, - 0x6e, 0x22, 0xfb, 0x01, 0x0a, 0x14, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, - 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, - 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, - 0xde, 0x01, 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, - 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, - 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, - 0x72, 0x6f, 0x77, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, - 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, - 0x22, 0x69, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, - 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, - 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1c, 0x0a, - 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x58, 0x0a, 0x0b, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, - 0x74, 0x70, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, - 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, - 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, - 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, 0x0b, 0x4f, 0x6e, 0x44, 0x44, - 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, - 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, - 0x04, 0x45, 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x45, 0x43, 0x5f, - 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0x7b, 0x0a, 0x18, 0x56, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x69, 0x7a, 0x65, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, - 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, - 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x65, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, - 0x44, 0x44, 0x4c, 0x10, 0x05, 0x2a, 0x44, 0x0a, 0x1b, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0b, - 0x0a, 0x07, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x41, - 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x70, 0x79, 0x10, 0x02, 0x2a, 0x71, 0x0a, 0x19, 0x56, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x10, 0x01, 0x12, - 0x0b, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, - 0x43, 0x6f, 0x70, 0x79, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x75, 0x6e, - 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, - 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x61, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x10, 0x06, 0x2a, 0x8d, - 0x02, 0x0a, 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, - 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, - 0x49, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, - 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, - 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, - 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, - 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, - 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, - 0x45, 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, - 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, - 0x12, 0x09, 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, - 0x45, 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, - 0x54, 0x49, 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, - 0x10, 0x10, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, - 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, - 0x41, 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, - 0x50, 0x59, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x14, 0x2a, 0x27, - 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, - 0x48, 0x41, 0x52, 0x44, 0x53, 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, - 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, - 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, 0x0b, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, + 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, + 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x49, 0x47, + 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0x7b, 0x0a, 0x18, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x65, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x44, 0x44, + 0x4c, 0x10, 0x05, 0x2a, 0x44, 0x0a, 0x1b, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x74, 0x6f, + 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x70, 0x79, 0x10, 0x02, 0x2a, 0x71, 0x0a, 0x19, 0x56, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x10, 0x01, 0x12, 0x0b, 0x0a, + 0x07, 0x53, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x6f, + 0x70, 0x79, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x6e, 0x69, + 0x6e, 0x67, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x05, 0x12, + 0x0b, 0x0a, 0x07, 0x4c, 0x61, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x10, 0x06, 0x2a, 0x8d, 0x02, 0x0a, + 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, 0x44, + 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, 0x0a, + 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, + 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, 0x05, + 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, + 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, + 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x54, + 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, 0x09, + 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, 0x41, + 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, 0x49, + 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x10, + 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, 0x0a, + 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, 0x56, + 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x50, 0x59, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x14, 0x2a, 0x27, 0x0a, 0x0d, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, + 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, + 0x52, 0x44, 0x53, 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, + 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3631,61 +3652,62 @@ var file_binlogdata_proto_depIdxs = []int32{ 48, // 16: binlogdata.RowChange.before:type_name -> query.Row 48, // 17: binlogdata.RowChange.after:type_name -> query.Row 43, // 18: binlogdata.RowChange.data_columns:type_name -> binlogdata.RowChange.Bitmap - 18, // 19: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange - 49, // 20: binlogdata.FieldEvent.fields:type_name -> query.Field - 36, // 21: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK - 21, // 22: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid - 5, // 23: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType - 21, // 24: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid - 23, // 25: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard - 4, // 26: binlogdata.VEvent.type:type_name -> binlogdata.VEventType - 19, // 27: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent - 20, // 28: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent - 22, // 29: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid - 24, // 30: binlogdata.VEvent.journal:type_name -> binlogdata.Journal - 35, // 31: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent - 49, // 32: binlogdata.MinimalTable.fields:type_name -> query.Field - 26, // 33: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable - 44, // 34: binlogdata.VStreamOptions.config_overrides:type_name -> binlogdata.VStreamOptions.ConfigOverridesEntry - 50, // 35: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID - 51, // 36: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 52, // 37: binlogdata.VStreamRequest.target:type_name -> query.Target - 16, // 38: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter - 36, // 39: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK - 28, // 40: binlogdata.VStreamRequest.options:type_name -> binlogdata.VStreamOptions - 25, // 41: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent - 50, // 42: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 51, // 43: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 52, // 44: binlogdata.VStreamRowsRequest.target:type_name -> query.Target - 53, // 45: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult - 28, // 46: binlogdata.VStreamRowsRequest.options:type_name -> binlogdata.VStreamOptions - 49, // 47: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field - 49, // 48: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field - 48, // 49: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row - 48, // 50: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row - 50, // 51: binlogdata.VStreamTablesRequest.effective_caller_id:type_name -> vtrpc.CallerID - 51, // 52: binlogdata.VStreamTablesRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 52, // 53: binlogdata.VStreamTablesRequest.target:type_name -> query.Target - 28, // 54: binlogdata.VStreamTablesRequest.options:type_name -> binlogdata.VStreamOptions - 49, // 55: binlogdata.VStreamTablesResponse.fields:type_name -> query.Field - 49, // 56: binlogdata.VStreamTablesResponse.pkfields:type_name -> query.Field - 48, // 57: binlogdata.VStreamTablesResponse.rows:type_name -> query.Row - 48, // 58: binlogdata.VStreamTablesResponse.lastpk:type_name -> query.Row - 36, // 59: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK - 53, // 60: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult - 50, // 61: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 51, // 62: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 52, // 63: binlogdata.VStreamResultsRequest.target:type_name -> query.Target - 49, // 64: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field - 48, // 65: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row - 6, // 66: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category - 8, // 67: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset - 14, // 68: binlogdata.Rule.ConvertCharsetEntry.value:type_name -> binlogdata.CharsetConversion - 69, // [69:69] is the sub-list for method output_type - 69, // [69:69] is the sub-list for method input_type - 69, // [69:69] is the sub-list for extension type_name - 69, // [69:69] is the sub-list for extension extendee - 0, // [0:69] is the sub-list for field type_name + 43, // 19: binlogdata.RowChange.json_partial_values:type_name -> binlogdata.RowChange.Bitmap + 18, // 20: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange + 49, // 21: binlogdata.FieldEvent.fields:type_name -> query.Field + 36, // 22: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK + 21, // 23: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid + 5, // 24: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType + 21, // 25: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid + 23, // 26: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard + 4, // 27: binlogdata.VEvent.type:type_name -> binlogdata.VEventType + 19, // 28: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent + 20, // 29: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent + 22, // 30: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid + 24, // 31: binlogdata.VEvent.journal:type_name -> binlogdata.Journal + 35, // 32: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent + 49, // 33: binlogdata.MinimalTable.fields:type_name -> query.Field + 26, // 34: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable + 44, // 35: binlogdata.VStreamOptions.config_overrides:type_name -> binlogdata.VStreamOptions.ConfigOverridesEntry + 50, // 36: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID + 51, // 37: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 52, // 38: binlogdata.VStreamRequest.target:type_name -> query.Target + 16, // 39: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter + 36, // 40: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK + 28, // 41: binlogdata.VStreamRequest.options:type_name -> binlogdata.VStreamOptions + 25, // 42: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent + 50, // 43: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 51, // 44: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 52, // 45: binlogdata.VStreamRowsRequest.target:type_name -> query.Target + 53, // 46: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult + 28, // 47: binlogdata.VStreamRowsRequest.options:type_name -> binlogdata.VStreamOptions + 49, // 48: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field + 49, // 49: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field + 48, // 50: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row + 48, // 51: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row + 50, // 52: binlogdata.VStreamTablesRequest.effective_caller_id:type_name -> vtrpc.CallerID + 51, // 53: binlogdata.VStreamTablesRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 52, // 54: binlogdata.VStreamTablesRequest.target:type_name -> query.Target + 28, // 55: binlogdata.VStreamTablesRequest.options:type_name -> binlogdata.VStreamOptions + 49, // 56: binlogdata.VStreamTablesResponse.fields:type_name -> query.Field + 49, // 57: binlogdata.VStreamTablesResponse.pkfields:type_name -> query.Field + 48, // 58: binlogdata.VStreamTablesResponse.rows:type_name -> query.Row + 48, // 59: binlogdata.VStreamTablesResponse.lastpk:type_name -> query.Row + 36, // 60: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK + 53, // 61: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult + 50, // 62: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 51, // 63: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 52, // 64: binlogdata.VStreamResultsRequest.target:type_name -> query.Target + 49, // 65: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field + 48, // 66: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row + 6, // 67: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category + 8, // 68: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset + 14, // 69: binlogdata.Rule.ConvertCharsetEntry.value:type_name -> binlogdata.CharsetConversion + 70, // [70:70] is the sub-list for method output_type + 70, // [70:70] is the sub-list for method input_type + 70, // [70:70] is the sub-list for extension type_name + 70, // [70:70] is the sub-list for extension extendee + 0, // [0:70] is the sub-list for field type_name } func init() { file_binlogdata_proto_init() } diff --git a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go index 98fba617973..93b378738dd 100644 --- a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go +++ b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go @@ -314,6 +314,7 @@ func (m *RowChange) CloneVT() *RowChange { r.Before = m.Before.CloneVT() r.After = m.After.CloneVT() r.DataColumns = m.DataColumns.CloneVT() + r.JsonPartialValues = m.JsonPartialValues.CloneVT() if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -1675,6 +1676,16 @@ func (m *RowChange) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.JsonPartialValues != nil { + size, err := m.JsonPartialValues.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } if m.DataColumns != nil { size, err := m.DataColumns.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -3636,6 +3647,10 @@ func (m *RowChange) SizeVT() (n int) { l = m.DataColumns.SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + if m.JsonPartialValues != nil { + l = m.JsonPartialValues.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -6619,6 +6634,42 @@ func (m *RowChange) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JsonPartialValues", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.JsonPartialValues == nil { + m.JsonPartialValues = &RowChange_Bitmap{} + } + if err := m.JsonPartialValues.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/go/vt/proto/query/cached_size.go b/go/vt/proto/query/cached_size.go index 5b613317294..4436594681a 100644 --- a/go/vt/proto/query/cached_size.go +++ b/go/vt/proto/query/cached_size.go @@ -27,6 +27,10 @@ func (cached *BindVariable) CachedSize(alloc bool) int64 { if alloc { size += int64(96) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } // field Value []byte { size += hack.RuntimeAllocSize(int64(cap(cached.Value))) @@ -48,6 +52,10 @@ func (cached *Field) CachedSize(alloc bool) int64 { if alloc { size += int64(160) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } // field Name string size += hack.RuntimeAllocSize(int64(len(cached.Name))) // field Table string @@ -70,6 +78,10 @@ func (cached *QueryWarning) CachedSize(alloc bool) int64 { if alloc { size += int64(64) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } // field Message string size += hack.RuntimeAllocSize(int64(len(cached.Message))) return size @@ -82,6 +94,10 @@ func (cached *Target) CachedSize(alloc bool) int64 { if alloc { size += int64(96) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } // field Keyspace string size += hack.RuntimeAllocSize(int64(len(cached.Keyspace))) // field Shard string @@ -98,6 +114,10 @@ func (cached *Value) CachedSize(alloc bool) int64 { if alloc { size += int64(80) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } // field Value []byte { size += hack.RuntimeAllocSize(int64(cap(cached.Value))) diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go index 8c4bcb93f47..a168cc2d363 100644 --- a/go/vt/proto/query/query.pb.go +++ b/go/vt/proto/query/query.pb.go @@ -319,7 +319,11 @@ const ( // Properties: 35, IsQuoted. Type_VECTOR Type = 2083 // RAW specifies a type which won't be quoted but the value used as-is while encoding. + // Properties: 36, None. Type_RAW Type = 2084 + // ROW_TUPLE represents multiple rows. + // Properties: 37, None. + Type_ROW_TUPLE Type = 2085 ) // Enum value maps for Type. @@ -362,6 +366,7 @@ var ( 4130: "BITNUM", 2083: "VECTOR", 2084: "RAW", + 2085: "ROW_TUPLE", } Type_value = map[string]int32{ "NULL_TYPE": 0, @@ -401,6 +406,7 @@ var ( "BITNUM": 4130, "VECTOR": 2083, "RAW": 2084, + "ROW_TUPLE": 2085, } ) @@ -1397,6 +1403,11 @@ type ExecuteOptions struct { // // *ExecuteOptions_AuthoritativeTimeout Timeout isExecuteOptions_Timeout `protobuf_oneof:"timeout"` + // fetch_last_insert_id indicates that after executing a DML involving last_insert_id(x), + // a subsequent "SELECT last_insert_id()" should be performed to retrieve the updated value. + // This is to circumvent a bug where setting last_insert_id(x) to zero is not signaled by mysql + // https://bugs.mysql.com/bug.php?id=116939 + FetchLastInsertId bool `protobuf:"varint,18,opt,name=fetch_last_insert_id,json=fetchLastInsertId,proto3" json:"fetch_last_insert_id,omitempty"` } func (x *ExecuteOptions) Reset() { @@ -1527,6 +1538,13 @@ func (x *ExecuteOptions) GetAuthoritativeTimeout() int64 { return 0 } +func (x *ExecuteOptions) GetFetchLastInsertId() bool { + if x != nil { + return x.FetchLastInsertId + } + return false +} + type isExecuteOptions_Timeout interface { isExecuteOptions_Timeout() } @@ -1752,6 +1770,7 @@ type QueryResult struct { Rows []*Row `protobuf:"bytes,4,rep,name=rows,proto3" json:"rows,omitempty"` Info string `protobuf:"bytes,6,opt,name=info,proto3" json:"info,omitempty"` SessionStateChanges string `protobuf:"bytes,7,opt,name=session_state_changes,json=sessionStateChanges,proto3" json:"session_state_changes,omitempty"` + InsertIdChanged bool `protobuf:"varint,8,opt,name=insert_id_changed,json=insertIdChanged,proto3" json:"insert_id_changed,omitempty"` } func (x *QueryResult) Reset() { @@ -1826,6 +1845,13 @@ func (x *QueryResult) GetSessionStateChanges() string { return "" } +func (x *QueryResult) GetInsertIdChanged() bool { + if x != nil { + return x.InsertIdChanged + } + return false +} + // QueryWarning is used to convey out of band query execution warnings // by storing in the vtgate.Session type QueryWarning struct { @@ -5855,7 +5881,7 @@ var file_query_proto_rawDesc = []byte{ 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0xda, 0x0b, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x8b, 0x0c, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4d, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, @@ -5906,220 +5932,208 @@ var file_query_proto_rawDesc = []byte{ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x22, 0x3b, 0x0a, 0x0e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4e, 0x44, 0x5f, - 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, - 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x22, 0x38, - 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4f, - 0x4c, 0x54, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x4c, 0x41, 0x50, 0x10, 0x02, 0x12, - 0x07, 0x0a, 0x03, 0x44, 0x42, 0x41, 0x10, 0x03, 0x22, 0xa7, 0x01, 0x0a, 0x14, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x13, - 0x0a, 0x0f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x52, 0x45, 0x41, - 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, - 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x41, 0x44, 0x5f, - 0x55, 0x4e, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x10, 0x0a, - 0x0c, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x12, - 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x4e, - 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, - 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x55, 0x54, 0x4f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, - 0x10, 0x06, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, - 0x5f, 0x50, 0x4c, 0x41, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x56, 0x33, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x65, 0x6e, 0x34, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, - 0x47, 0x65, 0x6e, 0x34, 0x47, 0x72, 0x65, 0x65, 0x64, 0x79, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, - 0x47, 0x65, 0x6e, 0x34, 0x4c, 0x65, 0x66, 0x74, 0x32, 0x52, 0x69, 0x67, 0x68, 0x74, 0x10, 0x04, - 0x12, 0x14, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x34, 0x57, 0x69, 0x74, 0x68, 0x46, 0x61, 0x6c, 0x6c, - 0x62, 0x61, 0x63, 0x6b, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x34, 0x43, 0x6f, - 0x6d, 0x70, 0x61, 0x72, 0x65, 0x56, 0x33, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x56, 0x33, 0x49, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x07, 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x53, - 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, - 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x43, - 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x41, 0x42, - 0x4c, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x53, 0x10, 0x03, 0x22, 0x4f, - 0x0a, 0x15, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x53, 0x49, - 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x00, - 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, - 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x42, - 0x09, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, - 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xb8, 0x02, 0x0a, - 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x72, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, - 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, - 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, - 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, - 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x72, 0x73, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x37, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, 0x18, - 0x0a, 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x12, 0x52, - 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x22, 0xe3, 0x01, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x72, - 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, - 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, - 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x3c, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x57, - 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0xa0, 0x03, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0a, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x9e, 0x02, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x08, 0x63, - 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x12, 0x38, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, - 0x73, 0x71, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x22, 0x27, - 0x0a, 0x08, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x4d, 0x4c, 0x10, 0x01, 0x12, 0x07, - 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, 0x02, 0x22, 0xe1, 0x02, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, - 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, - 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x3d, 0x0a, 0x0f, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x64, 0x0a, 0x0f, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x57, 0x69, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, - 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x22, 0xe7, 0x02, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, - 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, - 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x15, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0xee, 0x01, 0x0a, 0x0c, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, - 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x22, 0xa4, 0x01, 0x0a, 0x0d, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, - 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, - 0x31, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x49, 0x64, 0x22, 0xe7, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, + 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x11, 0x66, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x49, 0x64, 0x22, 0x3b, 0x0a, 0x0e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4e, 0x44, + 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x22, + 0x38, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, + 0x4f, 0x4c, 0x54, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x4c, 0x41, 0x50, 0x10, 0x02, + 0x12, 0x07, 0x0a, 0x03, 0x44, 0x42, 0x41, 0x10, 0x03, 0x22, 0xa7, 0x01, 0x0a, 0x14, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, + 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x43, 0x4f, 0x4d, + 0x4d, 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x41, 0x44, + 0x5f, 0x55, 0x4e, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x10, + 0x0a, 0x0c, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, + 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, + 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, + 0x59, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x55, 0x54, 0x4f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, + 0x54, 0x10, 0x06, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, + 0x54, 0x5f, 0x50, 0x4c, 0x41, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x56, + 0x33, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x65, 0x6e, 0x34, 0x10, 0x02, 0x12, 0x0e, 0x0a, + 0x0a, 0x47, 0x65, 0x6e, 0x34, 0x47, 0x72, 0x65, 0x65, 0x64, 0x79, 0x10, 0x03, 0x12, 0x12, 0x0a, + 0x0e, 0x47, 0x65, 0x6e, 0x34, 0x4c, 0x65, 0x66, 0x74, 0x32, 0x52, 0x69, 0x67, 0x68, 0x74, 0x10, + 0x04, 0x12, 0x14, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x34, 0x57, 0x69, 0x74, 0x68, 0x46, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x34, 0x43, + 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x56, 0x33, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x56, 0x33, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x07, 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, + 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, + 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x53, 0x4f, + 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, + 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x41, + 0x42, 0x4c, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x53, 0x10, 0x03, 0x22, + 0x4f, 0x0a, 0x15, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x53, + 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, + 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, + 0x42, 0x09, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10, + 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xb8, 0x02, + 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x72, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6f, + 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, + 0x72, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, + 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x37, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, + 0x18, 0x0a, 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x12, + 0x52, 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x22, 0x8f, 0x02, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, + 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x77, 0x73, 0x5f, + 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, + 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, + 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4a, 0x04, 0x08, + 0x05, 0x10, 0x06, 0x22, 0x3c, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x57, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0xa0, 0x03, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x32, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x1a, 0x9e, 0x02, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x41, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x10, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, + 0x38, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x71, 0x6c, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x22, 0x27, 0x0a, 0x08, 0x43, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x4d, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x44, + 0x44, 0x4c, 0x10, 0x02, 0x22, 0xe1, 0x02, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, + 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, + 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x3d, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x64, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x57, 0x69, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, + 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe7, 0x02, + 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, + 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, + 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, + 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, + 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xee, 0x01, 0x0a, + 0x0c, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, + 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa4, 0x01, + 0x0a, 0x0d, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x13, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, @@ -6133,81 +6147,29 @@ var file_query_proto_rawDesc = []byte{ 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x10, - 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, - 0x64, 0x22, 0xfa, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x11, - 0x0a, 0x0f, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xda, 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, - 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, - 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, - 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x18, - 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x02, 0x0a, 0x17, 0x52, 0x6f, 0x6c, - 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1a, - 0x0a, 0x18, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x90, 0x02, 0x0a, 0x18, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, - 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, - 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x1b, 0x0a, - 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x31, 0x0a, 0x0e, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, + 0xe7, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, + 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x10, 0x52, 0x6f, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0xfa, + 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, @@ -6222,31 +6184,10 @@ var file_query_proto_rawDesc = []byte{ 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x44, 0x0a, 0x13, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x17, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, - 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, - 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, - 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x1a, 0x43, 0x6f, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x50, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xda, + 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, @@ -6258,10 +6199,85 @@ var file_query_proto_rawDesc = []byte{ 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x43, - 0x6f, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x16, 0x52, - 0x65, 0x61, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x02, 0x0a, 0x17, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, + 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x52, + 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x90, 0x02, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, + 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, + 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x44, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xfe, + 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x74, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, + 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, @@ -6274,130 +6290,30 @@ var file_query_proto_rawDesc = []byte{ 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xef, 0x01, 0x0a, 0x1d, - 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, - 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, - 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, - 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0a, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x41, 0x67, 0x65, 0x22, 0x60, 0x0a, - 0x1e, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3e, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, - 0xe0, 0x02, 0x0a, 0x13, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, - 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, - 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, - 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, - 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x14, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, - 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x22, 0xe6, 0x02, 0x0a, 0x19, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, - 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, - 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x84, 0x02, 0x0a, - 0x1a, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, - 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, - 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, - 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x43, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x22, 0xf6, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x41, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, + 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x43, 0x6f, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x61, 0x64, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, + 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xef, 0x01, 0x0a, 0x1d, 0x55, 0x6e, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, @@ -6408,16 +6324,94 @@ var file_query_proto_rawDesc = []byte{ 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, - 0x03, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x40, 0x0a, - 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0xe8, 0x02, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, + 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x62, 0x61, + 0x6e, 0x64, 0x6f, 0x6e, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, + 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x41, 0x67, 0x65, 0x22, 0x60, 0x0a, 0x1e, 0x55, 0x6e, + 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0c, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0c, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe0, 0x02, 0x0a, + 0x13, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, + 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, + 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, + 0xfe, 0x01, 0x0a, 0x14, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x22, 0xe6, 0x02, 0x0a, 0x19, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, + 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, + 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, + 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x84, 0x02, 0x0a, 0x1a, 0x42, 0x65, + 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x22, 0xd9, 0x01, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, @@ -6428,349 +6422,388 @@ var file_query_proto_rawDesc = []byte{ 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x43, 0x0a, 0x15, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0xf6, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, + 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x69, 0x64, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x40, 0x0a, 0x12, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe8, 0x02, 0x0a, + 0x15, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, + 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, + 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, + 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x25, + 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, + 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x22, 0xee, 0x02, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, - 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x16, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x22, 0xee, 0x02, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, - 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, - 0x72, 0x69, 0x65, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x22, 0xf4, 0x02, 0x0a, 0x1a, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, - 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, - 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, - 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, - 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x74, 0x42, 0x65, - 0x67, 0x69, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa6, 0x02, 0x0a, 0x1b, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, - 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, - 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x22, 0xfa, 0x02, 0x0a, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, - 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, - 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, - 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, - 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, - 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, - 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, - 0x70, 0x6f, 0x73, 0x74, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x22, 0xac, 0x02, 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, - 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, - 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, - 0x87, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, - 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x52, 0x65, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0xbe, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x65, 0x70, 0x6c, + 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, + 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x22, 0xf4, 0x02, 0x0a, 0x1a, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, + 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, + 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, + 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, + 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x74, 0x42, 0x65, 0x67, 0x69, 0x6e, + 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa6, 0x02, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, + 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, + 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x22, 0xfa, 0x02, 0x0a, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, + 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, + 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, + 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, + 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6f, 0x73, + 0x74, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xac, 0x02, + 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, + 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, + 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x87, 0x02, 0x0a, + 0x0e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, + 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0xbe, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x30, 0x0a, + 0x14, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x47, 0x0a, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, - 0x12, 0x30, 0x0a, 0x14, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, + 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1d, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, + 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75, 0x5f, + 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x63, 0x70, 0x75, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x70, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x03, 0x71, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x69, 0x65, + 0x77, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x76, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x64, 0x66, + 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0b, 0x75, 0x64, 0x66, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, + 0x74, 0x78, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0c, 0x74, 0x78, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x64, 0x22, 0xf6, 0x01, 0x0a, 0x0e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x5f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x12, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x75, 0x6e, 0x68, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x75, 0x6e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x1b, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, + 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x69, 0x6e, 0x12, 0x3d, 0x0a, 0x1b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x73, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1d, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, - 0x70, 0x75, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, - 0x63, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x70, 0x73, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x71, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, - 0x76, 0x69, 0x65, 0x77, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x64, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x76, 0x69, 0x65, 0x77, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, - 0x75, 0x64, 0x66, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0b, 0x75, 0x64, 0x66, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, - 0x23, 0x0a, 0x0d, 0x74, 0x78, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x74, 0x78, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, - 0x6c, 0x76, 0x65, 0x64, 0x22, 0xf6, 0x01, 0x0a, 0x0e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x75, 0x6e, 0x68, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x75, 0x6e, 0x68, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x3d, 0x0a, 0x1b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, - 0x61, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x69, 0x6e, 0x12, 0x3d, - 0x0a, 0x1b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, - 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x78, 0x22, 0x95, 0x02, - 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x5f, 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x54, 0x65, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x61, 0x6c, - 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x4a, - 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0xae, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, - 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, - 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x17, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, - 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, - 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x6d, 0x0a, 0x07, 0x55, 0x44, - 0x46, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x0b, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x11, 0x47, 0x65, - 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x22, 0x0a, 0x04, 0x75, 0x64, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x55, 0x44, 0x46, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x75, - 0x64, 0x66, 0x73, 0x12, 0x58, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x42, 0x0a, - 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x2a, 0x92, 0x03, 0x0a, 0x09, 0x4d, 0x79, 0x53, 0x71, 0x6c, 0x46, 0x6c, 0x61, 0x67, 0x12, - 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x4f, - 0x54, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, - 0x0c, 0x50, 0x52, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x02, 0x12, - 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, - 0x41, 0x47, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, - 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x08, 0x12, 0x0d, 0x0a, 0x09, 0x42, - 0x4c, 0x4f, 0x42, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x10, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, - 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x20, 0x12, 0x11, 0x0a, - 0x0d, 0x5a, 0x45, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x40, - 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, - 0x80, 0x01, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, - 0x80, 0x02, 0x12, 0x18, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x49, 0x4e, 0x43, 0x52, 0x45, - 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x04, 0x12, 0x13, 0x0a, 0x0e, - 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, - 0x08, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x45, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x10, - 0x12, 0x1a, 0x0a, 0x15, 0x4e, 0x4f, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x56, - 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x20, 0x12, 0x17, 0x0a, 0x12, - 0x4f, 0x4e, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x57, 0x5f, 0x46, 0x4c, - 0x41, 0x47, 0x10, 0x80, 0x40, 0x12, 0x0e, 0x0a, 0x08, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x4c, 0x41, - 0x47, 0x10, 0x80, 0x80, 0x02, 0x12, 0x13, 0x0a, 0x0d, 0x50, 0x41, 0x52, 0x54, 0x5f, 0x4b, 0x45, - 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x47, 0x52, - 0x4f, 0x55, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x02, 0x12, 0x11, 0x0a, 0x0b, - 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x04, 0x12, - 0x11, 0x0a, 0x0b, 0x42, 0x49, 0x4e, 0x43, 0x4d, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, - 0x80, 0x08, 0x1a, 0x02, 0x10, 0x01, 0x2a, 0x6b, 0x0a, 0x04, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x08, - 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x49, 0x4e, - 0x54, 0x45, 0x47, 0x52, 0x41, 0x4c, 0x10, 0x80, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x55, - 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x10, 0x80, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x53, - 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x80, 0x08, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x53, 0x51, 0x55, - 0x4f, 0x54, 0x45, 0x44, 0x10, 0x80, 0x10, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x53, 0x54, 0x45, 0x58, - 0x54, 0x10, 0x80, 0x20, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x53, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, - 0x10, 0x80, 0x40, 0x2a, 0xd7, 0x03, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, 0x09, - 0x4e, 0x55, 0x4c, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x04, 0x49, - 0x4e, 0x54, 0x38, 0x10, 0x81, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x55, 0x49, 0x4e, 0x54, 0x38, 0x10, - 0x82, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x31, 0x36, 0x10, 0x83, 0x02, 0x12, 0x0b, - 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x31, 0x36, 0x10, 0x84, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, - 0x4e, 0x54, 0x32, 0x34, 0x10, 0x85, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x32, - 0x34, 0x10, 0x86, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x87, 0x02, - 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x88, 0x06, 0x12, 0x0a, 0x0a, - 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x89, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, - 0x54, 0x36, 0x34, 0x10, 0x8a, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x33, - 0x32, 0x10, 0x8b, 0x08, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x36, 0x34, 0x10, - 0x8c, 0x08, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, - 0x8d, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, 0x10, 0x8e, 0x10, 0x12, 0x09, 0x0a, - 0x04, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x8f, 0x10, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x41, 0x54, 0x45, - 0x54, 0x49, 0x4d, 0x45, 0x10, 0x90, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x59, 0x45, 0x41, 0x52, 0x10, - 0x91, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x43, 0x49, 0x4d, 0x41, 0x4c, 0x10, 0x12, 0x12, - 0x09, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, 0x93, 0x30, 0x12, 0x09, 0x0a, 0x04, 0x42, 0x4c, - 0x4f, 0x42, 0x10, 0x94, 0x50, 0x12, 0x0c, 0x0a, 0x07, 0x56, 0x41, 0x52, 0x43, 0x48, 0x41, 0x52, - 0x10, 0x95, 0x30, 0x12, 0x0e, 0x0a, 0x09, 0x56, 0x41, 0x52, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, - 0x10, 0x96, 0x50, 0x12, 0x09, 0x0a, 0x04, 0x43, 0x48, 0x41, 0x52, 0x10, 0x97, 0x30, 0x12, 0x0b, - 0x0a, 0x06, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x98, 0x50, 0x12, 0x08, 0x0a, 0x03, 0x42, - 0x49, 0x54, 0x10, 0x99, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x9a, 0x10, - 0x12, 0x08, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x9b, 0x10, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x55, - 0x50, 0x4c, 0x45, 0x10, 0x1c, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, - 0x59, 0x10, 0x9d, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x9e, 0x10, 0x12, - 0x0e, 0x0a, 0x0a, 0x45, 0x58, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x1f, 0x12, - 0x0b, 0x0a, 0x06, 0x48, 0x45, 0x58, 0x4e, 0x55, 0x4d, 0x10, 0xa0, 0x20, 0x12, 0x0b, 0x0a, 0x06, - 0x48, 0x45, 0x58, 0x56, 0x41, 0x4c, 0x10, 0xa1, 0x20, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x49, 0x54, - 0x4e, 0x55, 0x4d, 0x10, 0xa2, 0x20, 0x12, 0x0b, 0x0a, 0x06, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, - 0x10, 0xa3, 0x10, 0x12, 0x08, 0x0a, 0x03, 0x52, 0x41, 0x57, 0x10, 0xa4, 0x10, 0x2a, 0x36, 0x0a, - 0x10, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x08, - 0x0a, 0x04, 0x46, 0x61, 0x69, 0x6c, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x10, 0x02, 0x2a, 0x46, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, - 0x45, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, - 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x2a, 0x3b, 0x0a, - 0x0f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x45, 0x57, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, - 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x02, - 0x12, 0x08, 0x0a, 0x04, 0x55, 0x44, 0x46, 0x53, 0x10, 0x03, 0x42, 0x35, 0x0a, 0x0f, 0x69, 0x6f, - 0x2e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x22, 0x76, - 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, - 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x78, 0x22, 0x95, 0x02, 0x0a, 0x14, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x6e, 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, + 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x54, 0x65, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x4a, 0x04, 0x08, 0x06, + 0x10, 0x07, 0x22, 0xae, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x12, 0x2d, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, + 0x6e, 0x74, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x6d, 0x0a, 0x07, 0x55, 0x44, 0x46, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, + 0x75, 0x64, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x55, 0x44, 0x46, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x75, 0x64, 0x66, 0x73, + 0x12, 0x58, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x42, 0x0a, 0x14, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x92, + 0x03, 0x0a, 0x09, 0x4d, 0x79, 0x53, 0x71, 0x6c, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x09, 0x0a, 0x05, + 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x4f, 0x54, 0x5f, 0x4e, + 0x55, 0x4c, 0x4c, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, + 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, + 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, + 0x04, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, 0x5f, 0x4b, 0x45, + 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x08, 0x12, 0x0d, 0x0a, 0x09, 0x42, 0x4c, 0x4f, 0x42, + 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x10, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x53, 0x49, 0x47, + 0x4e, 0x45, 0x44, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x20, 0x12, 0x11, 0x0a, 0x0d, 0x5a, 0x45, + 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x40, 0x12, 0x10, 0x0a, + 0x0b, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x01, 0x12, + 0x0e, 0x0a, 0x09, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x02, 0x12, + 0x18, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x49, 0x4e, 0x43, 0x52, 0x45, 0x4d, 0x45, 0x4e, + 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x04, 0x12, 0x13, 0x0a, 0x0e, 0x54, 0x49, 0x4d, + 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x08, 0x12, 0x0d, + 0x0a, 0x08, 0x53, 0x45, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x10, 0x12, 0x1a, 0x0a, + 0x15, 0x4e, 0x4f, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, + 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x20, 0x12, 0x17, 0x0a, 0x12, 0x4f, 0x4e, 0x5f, + 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x57, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, + 0x80, 0x40, 0x12, 0x0e, 0x0a, 0x08, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, + 0x80, 0x02, 0x12, 0x13, 0x0a, 0x0d, 0x50, 0x41, 0x52, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, + 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x47, 0x52, 0x4f, 0x55, 0x50, + 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x02, 0x12, 0x11, 0x0a, 0x0b, 0x55, 0x4e, 0x49, + 0x51, 0x55, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x04, 0x12, 0x11, 0x0a, 0x0b, + 0x42, 0x49, 0x4e, 0x43, 0x4d, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x08, 0x1a, + 0x02, 0x10, 0x01, 0x2a, 0x6b, 0x0a, 0x04, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, + 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x49, 0x4e, 0x54, 0x45, 0x47, + 0x52, 0x41, 0x4c, 0x10, 0x80, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x55, 0x4e, 0x53, 0x49, + 0x47, 0x4e, 0x45, 0x44, 0x10, 0x80, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x53, 0x46, 0x4c, 0x4f, + 0x41, 0x54, 0x10, 0x80, 0x08, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x53, 0x51, 0x55, 0x4f, 0x54, 0x45, + 0x44, 0x10, 0x80, 0x10, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x53, 0x54, 0x45, 0x58, 0x54, 0x10, 0x80, + 0x20, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x53, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x80, 0x40, + 0x2a, 0xe7, 0x03, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x55, 0x4c, + 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x04, 0x49, 0x4e, 0x54, 0x38, + 0x10, 0x81, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x55, 0x49, 0x4e, 0x54, 0x38, 0x10, 0x82, 0x06, 0x12, + 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x31, 0x36, 0x10, 0x83, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, + 0x49, 0x4e, 0x54, 0x31, 0x36, 0x10, 0x84, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x32, + 0x34, 0x10, 0x85, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x32, 0x34, 0x10, 0x86, + 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x87, 0x02, 0x12, 0x0b, 0x0a, + 0x06, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x88, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, + 0x54, 0x36, 0x34, 0x10, 0x89, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, + 0x10, 0x8a, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x33, 0x32, 0x10, 0x8b, + 0x08, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x36, 0x34, 0x10, 0x8c, 0x08, 0x12, + 0x0e, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x8d, 0x10, 0x12, + 0x09, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, 0x10, 0x8e, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x49, + 0x4d, 0x45, 0x10, 0x8f, 0x10, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x41, 0x54, 0x45, 0x54, 0x49, 0x4d, + 0x45, 0x10, 0x90, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x59, 0x45, 0x41, 0x52, 0x10, 0x91, 0x06, 0x12, + 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x43, 0x49, 0x4d, 0x41, 0x4c, 0x10, 0x12, 0x12, 0x09, 0x0a, 0x04, + 0x54, 0x45, 0x58, 0x54, 0x10, 0x93, 0x30, 0x12, 0x09, 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, + 0x94, 0x50, 0x12, 0x0c, 0x0a, 0x07, 0x56, 0x41, 0x52, 0x43, 0x48, 0x41, 0x52, 0x10, 0x95, 0x30, + 0x12, 0x0e, 0x0a, 0x09, 0x56, 0x41, 0x52, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x96, 0x50, + 0x12, 0x09, 0x0a, 0x04, 0x43, 0x48, 0x41, 0x52, 0x10, 0x97, 0x30, 0x12, 0x0b, 0x0a, 0x06, 0x42, + 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x98, 0x50, 0x12, 0x08, 0x0a, 0x03, 0x42, 0x49, 0x54, 0x10, + 0x99, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x9a, 0x10, 0x12, 0x08, 0x0a, + 0x03, 0x53, 0x45, 0x54, 0x10, 0x9b, 0x10, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x55, 0x50, 0x4c, 0x45, + 0x10, 0x1c, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, 0x10, 0x9d, + 0x10, 0x12, 0x09, 0x0a, 0x04, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x9e, 0x10, 0x12, 0x0e, 0x0a, 0x0a, + 0x45, 0x58, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x1f, 0x12, 0x0b, 0x0a, 0x06, + 0x48, 0x45, 0x58, 0x4e, 0x55, 0x4d, 0x10, 0xa0, 0x20, 0x12, 0x0b, 0x0a, 0x06, 0x48, 0x45, 0x58, + 0x56, 0x41, 0x4c, 0x10, 0xa1, 0x20, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x49, 0x54, 0x4e, 0x55, 0x4d, + 0x10, 0xa2, 0x20, 0x12, 0x0b, 0x0a, 0x06, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x10, 0xa3, 0x10, + 0x12, 0x08, 0x0a, 0x03, 0x52, 0x41, 0x57, 0x10, 0xa4, 0x10, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x4f, + 0x57, 0x5f, 0x54, 0x55, 0x50, 0x4c, 0x45, 0x10, 0xa5, 0x10, 0x2a, 0x36, 0x0a, 0x10, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, + 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x46, + 0x61, 0x69, 0x6c, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x10, 0x02, 0x2a, 0x46, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x45, 0x10, 0x01, + 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x0a, + 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x2a, 0x3b, 0x0a, 0x0f, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, + 0x05, 0x56, 0x49, 0x45, 0x57, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, + 0x45, 0x53, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x08, 0x0a, + 0x04, 0x55, 0x44, 0x46, 0x53, 0x10, 0x03, 0x42, 0x35, 0x0a, 0x0f, 0x69, 0x6f, 0x2e, 0x76, 0x69, + 0x74, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x22, 0x76, 0x69, 0x74, 0x65, + 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, + 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/go/vt/proto/query/query_vtproto.pb.go b/go/vt/proto/query/query_vtproto.pb.go index 2cb69d9406d..21ab8776fc5 100644 --- a/go/vt/proto/query/query_vtproto.pb.go +++ b/go/vt/proto/query/query_vtproto.pb.go @@ -176,6 +176,7 @@ func (m *ExecuteOptions) CloneVT() *ExecuteOptions { r.Consolidator = m.Consolidator r.WorkloadName = m.WorkloadName r.Priority = m.Priority + r.FetchLastInsertId = m.FetchLastInsertId if rhs := m.TransactionAccessMode; rhs != nil { tmpContainer := make([]ExecuteOptions_TransactionAccessMode, len(rhs)) copy(tmpContainer, rhs) @@ -268,6 +269,7 @@ func (m *QueryResult) CloneVT() *QueryResult { r.InsertId = m.InsertId r.Info = m.Info r.SessionStateChanges = m.SessionStateChanges + r.InsertIdChanged = m.InsertIdChanged if rhs := m.Fields; rhs != nil { tmpContainer := make([]*Field, len(rhs)) for k, v := range rhs { @@ -1893,6 +1895,18 @@ func (m *ExecuteOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { } i -= size } + if m.FetchLastInsertId { + i-- + if m.FetchLastInsertId { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x90 + } if len(m.Priority) > 0 { i -= len(m.Priority) copy(dAtA[i:], m.Priority) @@ -2198,6 +2212,16 @@ func (m *QueryResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.InsertIdChanged { + i-- + if m.InsertIdChanged { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } if len(m.SessionStateChanges) > 0 { i -= len(m.SessionStateChanges) copy(dAtA[i:], m.SessionStateChanges) @@ -6169,6 +6193,9 @@ func (m *ExecuteOptions) SizeVT() (n int) { if vtmsg, ok := m.Timeout.(interface{ SizeVT() int }); ok { n += vtmsg.SizeVT() } + if m.FetchLastInsertId { + n += 3 + } n += len(m.unknownFields) return n } @@ -6284,6 +6311,9 @@ func (m *QueryResult) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + if m.InsertIdChanged { + n += 2 + } n += len(m.unknownFields) return n } @@ -8914,6 +8944,26 @@ func (m *ExecuteOptions) UnmarshalVT(dAtA []byte) error { } } m.Timeout = &ExecuteOptions_AuthoritativeTimeout{AuthoritativeTimeout: v} + case 18: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FetchLastInsertId", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.FetchLastInsertId = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -9636,6 +9686,26 @@ func (m *QueryResult) UnmarshalVT(dAtA []byte) error { } m.SessionStateChanges = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InsertIdChanged", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.InsertIdChanged = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/go/vt/proto/replicationdata/replicationdata.pb.go b/go/vt/proto/replicationdata/replicationdata.pb.go index ab307dba9fa..bb973577d55 100644 --- a/go/vt/proto/replicationdata/replicationdata.pb.go +++ b/go/vt/proto/replicationdata/replicationdata.pb.go @@ -371,9 +371,8 @@ type StopReplicationStatus struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Before *Status `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"` - After *Status `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"` - BackupRunning bool `protobuf:"varint,3,opt,name=backup_running,json=backupRunning,proto3" json:"backup_running,omitempty"` + Before *Status `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"` + After *Status `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"` } func (x *StopReplicationStatus) Reset() { @@ -420,13 +419,6 @@ func (x *StopReplicationStatus) GetAfter() *Status { return nil } -func (x *StopReplicationStatus) GetBackupRunning() bool { - if x != nil { - return x.BackupRunning - } - return false -} - // PrimaryStatus is the replication status for a MySQL primary (returned by 'show binary log status'). type PrimaryStatus struct { state protoimpl.MessageState @@ -517,6 +509,7 @@ type FullStatus struct { SemiSyncWaitForReplicaCount uint32 `protobuf:"varint,20,opt,name=semi_sync_wait_for_replica_count,json=semiSyncWaitForReplicaCount,proto3" json:"semi_sync_wait_for_replica_count,omitempty"` SuperReadOnly bool `protobuf:"varint,21,opt,name=super_read_only,json=superReadOnly,proto3" json:"super_read_only,omitempty"` ReplicationConfiguration *Configuration `protobuf:"bytes,22,opt,name=replication_configuration,json=replicationConfiguration,proto3" json:"replication_configuration,omitempty"` + DiskStalled bool `protobuf:"varint,23,opt,name=disk_stalled,json=diskStalled,proto3" json:"disk_stalled,omitempty"` } func (x *FullStatus) Reset() { @@ -703,6 +696,13 @@ func (x *FullStatus) GetReplicationConfiguration() *Configuration { return nil } +func (x *FullStatus) GetDiskStalled() bool { + if x != nil { + return x.DiskStalled + } + return false +} + var File_replicationdata_proto protoreflect.FileDescriptor var file_replicationdata_proto_rawDesc = []byte{ @@ -775,100 +775,100 @@ var file_replicationdata_proto_rawDesc = []byte{ 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x6e, 0x65, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x4e, 0x65, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x9e, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x6f, - 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x2f, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x61, 0x66, 0x74, - 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x72, 0x75, 0x6e, - 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, 0x71, 0x0a, 0x0d, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, - 0x69, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x22, 0xc8, 0x08, 0x0a, - 0x0a, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x12, 0x46, 0x0a, 0x12, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x11, - 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x74, 0x69, 0x64, - 0x5f, 0x70, 0x75, 0x72, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, - 0x74, 0x69, 0x64, 0x50, 0x75, 0x72, 0x67, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x74, 0x69, - 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x74, - 0x69, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x6f, 0x77, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x6f, 0x77, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x6f, 0x67, 0x5f, 0x62, 0x69, 0x6e, - 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, - 0x6c, 0x6f, 0x67, 0x42, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2e, 0x0a, - 0x13, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6c, 0x6f, 0x67, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x39, 0x0a, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x77, 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x70, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x2f, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x22, 0x71, 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, + 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x75, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x55, 0x75, 0x69, 0x64, 0x22, 0xeb, 0x08, 0x0a, 0x0a, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, + 0x64, 0x12, 0x46, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x11, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x74, 0x69, 0x64, 0x5f, 0x70, 0x75, 0x72, 0x67, 0x65, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x74, 0x69, 0x64, 0x50, 0x75, 0x72, 0x67, 0x65, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, + 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, + 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x74, 0x69, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x74, 0x69, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x6f, + 0x77, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x6f, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, + 0x0f, 0x6c, 0x6f, 0x67, 0x5f, 0x62, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6c, 0x6f, 0x67, 0x42, 0x69, 0x6e, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x11, 0x6c, 0x6f, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, + 0x6e, 0x63, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, + 0x6e, 0x63, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x39, 0x0a, 0x19, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x16, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x18, 0x73, + 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, + 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, + 0x63, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, + 0x72, 0x79, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x19, 0x73, 0x65, 0x6d, 0x69, - 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x73, 0x65, 0x6d, - 0x69, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, - 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x37, 0x0a, 0x18, - 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, - 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, - 0x6e, 0x63, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, - 0x6e, 0x63, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, - 0x12, 0x39, 0x0a, 0x19, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x70, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x13, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x16, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x45, 0x0a, 0x20, 0x73, - 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x66, 0x6f, - 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1b, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x57, - 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, - 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x75, 0x70, - 0x65, 0x72, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x5b, 0x0a, 0x19, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x18, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x3b, 0x0a, 0x13, 0x53, 0x74, 0x6f, 0x70, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x12, - 0x0a, 0x0e, 0x49, 0x4f, 0x41, 0x4e, 0x44, 0x53, 0x51, 0x4c, 0x54, 0x48, 0x52, 0x45, 0x41, 0x44, - 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4f, 0x54, 0x48, 0x52, 0x45, 0x41, 0x44, 0x4f, 0x4e, - 0x4c, 0x59, 0x10, 0x01, 0x42, 0x2e, 0x5a, 0x2c, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, - 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x73, 0x65, 0x6d, 0x69, + 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x73, 0x65, 0x6d, + 0x69, 0x53, 0x79, 0x6e, 0x63, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x12, 0x45, 0x0a, 0x20, 0x73, 0x65, 0x6d, 0x69, 0x5f, 0x73, 0x79, 0x6e, 0x63, + 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1b, 0x73, + 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x15, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x65, 0x72, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x6e, + 0x6c, 0x79, 0x12, 0x5b, 0x0a, 0x19, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x2a, 0x3b, 0x0a, 0x13, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4f, 0x41, + 0x4e, 0x44, 0x53, 0x51, 0x4c, 0x54, 0x48, 0x52, 0x45, 0x41, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, + 0x0c, 0x49, 0x4f, 0x54, 0x48, 0x52, 0x45, 0x41, 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x42, + 0x2e, 0x5a, 0x2c, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, + 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/go/vt/proto/replicationdata/replicationdata_vtproto.pb.go b/go/vt/proto/replicationdata/replicationdata_vtproto.pb.go index 2bf3cb7788c..a515397c065 100644 --- a/go/vt/proto/replicationdata/replicationdata_vtproto.pb.go +++ b/go/vt/proto/replicationdata/replicationdata_vtproto.pb.go @@ -85,7 +85,6 @@ func (m *StopReplicationStatus) CloneVT() *StopReplicationStatus { r := new(StopReplicationStatus) r.Before = m.Before.CloneVT() r.After = m.After.CloneVT() - r.BackupRunning = m.BackupRunning if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -143,6 +142,7 @@ func (m *FullStatus) CloneVT() *FullStatus { r.SemiSyncWaitForReplicaCount = m.SemiSyncWaitForReplicaCount r.SuperReadOnly = m.SuperReadOnly r.ReplicationConfiguration = m.ReplicationConfiguration.CloneVT() + r.DiskStalled = m.DiskStalled if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -446,16 +446,6 @@ func (m *StopReplicationStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if m.BackupRunning { - i-- - if m.BackupRunning { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x18 - } if m.After != nil { size, err := m.After.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -563,6 +553,18 @@ func (m *FullStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.DiskStalled { + i-- + if m.DiskStalled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb8 + } if m.ReplicationConfiguration != nil { size, err := m.ReplicationConfiguration.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -878,9 +880,6 @@ func (m *StopReplicationStatus) SizeVT() (n int) { l = m.After.SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if m.BackupRunning { - n += 2 - } n += len(m.unknownFields) return n } @@ -989,6 +988,9 @@ func (m *FullStatus) SizeVT() (n int) { l = m.ReplicationConfiguration.SizeVT() n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) } + if m.DiskStalled { + n += 3 + } n += len(m.unknownFields) return n } @@ -1799,26 +1801,6 @@ func (m *StopReplicationStatus) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BackupRunning", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.BackupRunning = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -2585,6 +2567,26 @@ func (m *FullStatus) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 23: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DiskStalled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DiskStalled = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index 781373d6c76..02d9e715237 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -3098,8 +3098,7 @@ type ReplicationStatusResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Status *replicationdata.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` - BackupRunning bool `protobuf:"varint,2,opt,name=backup_running,json=backupRunning,proto3" json:"backup_running,omitempty"` + Status *replicationdata.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` } func (x *ReplicationStatusResponse) Reset() { @@ -3139,13 +3138,6 @@ func (x *ReplicationStatusResponse) GetStatus() *replicationdata.Status { return nil } -func (x *ReplicationStatusResponse) GetBackupRunning() bool { - if x != nil { - return x.BackupRunning - } - return false -} - type PrimaryStatusRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -5084,8 +5076,7 @@ type StopReplicationAndGetStatusResponse struct { unknownFields protoimpl.UnknownFields // Status represents the replication status call right before, and right after telling the replica to stop. - Status *replicationdata.StopReplicationStatus `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - BackupRunning bool `protobuf:"varint,3,opt,name=backup_running,json=backupRunning,proto3" json:"backup_running,omitempty"` + Status *replicationdata.StopReplicationStatus `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` } func (x *StopReplicationAndGetStatusResponse) Reset() { @@ -5125,13 +5116,6 @@ func (x *StopReplicationAndGetStatusResponse) GetStatus() *replicationdata.StopR return nil } -func (x *StopReplicationAndGetStatusResponse) GetBackupRunning() bool { - if x != nil { - return x.BackupRunning - } - return false -} - type PromoteReplicaRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6782,6 +6766,61 @@ func (x *VDiffOptions) GetReportOptions() *VDiffReportOptions { return nil } +type VDiffTableLastPK struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Target *query.QueryResult `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + // If the source value is nil then it's the same as the target + // and the target value should be used for both. + Source *query.QueryResult `protobuf:"bytes,2,opt,name=source,proto3,oneof" json:"source,omitempty"` +} + +func (x *VDiffTableLastPK) Reset() { + *x = VDiffTableLastPK{} + mi := &file_tabletmanagerdata_proto_msgTypes[132] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VDiffTableLastPK) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VDiffTableLastPK) ProtoMessage() {} + +func (x *VDiffTableLastPK) ProtoReflect() protoreflect.Message { + mi := &file_tabletmanagerdata_proto_msgTypes[132] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VDiffTableLastPK.ProtoReflect.Descriptor instead. +func (*VDiffTableLastPK) Descriptor() ([]byte, []int) { + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{132} +} + +func (x *VDiffTableLastPK) GetTarget() *query.QueryResult { + if x != nil { + return x.Target + } + return nil +} + +func (x *VDiffTableLastPK) GetSource() *query.QueryResult { + if x != nil { + return x.Source + } + return nil +} + // UpdateVReplicationWorkflowRequest is used to update an existing VReplication // workflow. Note that the following fields MUST have an explicit value provided // if you do NOT wish to update the existing value to the given type's ZeroValue: @@ -6799,12 +6838,14 @@ type UpdateVReplicationWorkflowRequest struct { TabletSelectionPreference *TabletSelectionPreference `protobuf:"varint,4,opt,name=tablet_selection_preference,json=tabletSelectionPreference,proto3,enum=tabletmanagerdata.TabletSelectionPreference,oneof" json:"tablet_selection_preference,omitempty"` OnDdl *binlogdata.OnDDLAction `protobuf:"varint,5,opt,name=on_ddl,json=onDdl,proto3,enum=binlogdata.OnDDLAction,oneof" json:"on_ddl,omitempty"` State *binlogdata.VReplicationWorkflowState `protobuf:"varint,6,opt,name=state,proto3,enum=binlogdata.VReplicationWorkflowState,oneof" json:"state,omitempty"` + Shards []string `protobuf:"bytes,7,rep,name=shards,proto3" json:"shards,omitempty"` ConfigOverrides map[string]string `protobuf:"bytes,8,rep,name=config_overrides,json=configOverrides,proto3" json:"config_overrides,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Message *string `protobuf:"bytes,9,opt,name=message,proto3,oneof" json:"message,omitempty"` } func (x *UpdateVReplicationWorkflowRequest) Reset() { *x = UpdateVReplicationWorkflowRequest{} - mi := &file_tabletmanagerdata_proto_msgTypes[132] + mi := &file_tabletmanagerdata_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6816,7 +6857,7 @@ func (x *UpdateVReplicationWorkflowRequest) String() string { func (*UpdateVReplicationWorkflowRequest) ProtoMessage() {} func (x *UpdateVReplicationWorkflowRequest) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[132] + mi := &file_tabletmanagerdata_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6829,7 +6870,7 @@ func (x *UpdateVReplicationWorkflowRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateVReplicationWorkflowRequest.ProtoReflect.Descriptor instead. func (*UpdateVReplicationWorkflowRequest) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{132} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{133} } func (x *UpdateVReplicationWorkflowRequest) GetWorkflow() string { @@ -6874,6 +6915,13 @@ func (x *UpdateVReplicationWorkflowRequest) GetState() binlogdata.VReplicationWo return binlogdata.VReplicationWorkflowState(0) } +func (x *UpdateVReplicationWorkflowRequest) GetShards() []string { + if x != nil { + return x.Shards + } + return nil +} + func (x *UpdateVReplicationWorkflowRequest) GetConfigOverrides() map[string]string { if x != nil { return x.ConfigOverrides @@ -6881,6 +6929,13 @@ func (x *UpdateVReplicationWorkflowRequest) GetConfigOverrides() map[string]stri return nil } +func (x *UpdateVReplicationWorkflowRequest) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + type UpdateVReplicationWorkflowResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6891,7 +6946,7 @@ type UpdateVReplicationWorkflowResponse struct { func (x *UpdateVReplicationWorkflowResponse) Reset() { *x = UpdateVReplicationWorkflowResponse{} - mi := &file_tabletmanagerdata_proto_msgTypes[133] + mi := &file_tabletmanagerdata_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6903,7 +6958,7 @@ func (x *UpdateVReplicationWorkflowResponse) String() string { func (*UpdateVReplicationWorkflowResponse) ProtoMessage() {} func (x *UpdateVReplicationWorkflowResponse) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[133] + mi := &file_tabletmanagerdata_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6916,7 +6971,7 @@ func (x *UpdateVReplicationWorkflowResponse) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateVReplicationWorkflowResponse.ProtoReflect.Descriptor instead. func (*UpdateVReplicationWorkflowResponse) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{133} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{134} } func (x *UpdateVReplicationWorkflowResponse) GetResult() *query.QueryResult { @@ -6947,7 +7002,7 @@ type UpdateVReplicationWorkflowsRequest struct { func (x *UpdateVReplicationWorkflowsRequest) Reset() { *x = UpdateVReplicationWorkflowsRequest{} - mi := &file_tabletmanagerdata_proto_msgTypes[134] + mi := &file_tabletmanagerdata_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6959,7 +7014,7 @@ func (x *UpdateVReplicationWorkflowsRequest) String() string { func (*UpdateVReplicationWorkflowsRequest) ProtoMessage() {} func (x *UpdateVReplicationWorkflowsRequest) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[134] + mi := &file_tabletmanagerdata_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6972,7 +7027,7 @@ func (x *UpdateVReplicationWorkflowsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateVReplicationWorkflowsRequest.ProtoReflect.Descriptor instead. func (*UpdateVReplicationWorkflowsRequest) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{134} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{135} } func (x *UpdateVReplicationWorkflowsRequest) GetAllWorkflows() bool { @@ -7027,7 +7082,7 @@ type UpdateVReplicationWorkflowsResponse struct { func (x *UpdateVReplicationWorkflowsResponse) Reset() { *x = UpdateVReplicationWorkflowsResponse{} - mi := &file_tabletmanagerdata_proto_msgTypes[135] + mi := &file_tabletmanagerdata_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7039,7 +7094,7 @@ func (x *UpdateVReplicationWorkflowsResponse) String() string { func (*UpdateVReplicationWorkflowsResponse) ProtoMessage() {} func (x *UpdateVReplicationWorkflowsResponse) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[135] + mi := &file_tabletmanagerdata_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7052,7 +7107,7 @@ func (x *UpdateVReplicationWorkflowsResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use UpdateVReplicationWorkflowsResponse.ProtoReflect.Descriptor instead. func (*UpdateVReplicationWorkflowsResponse) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{135} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{136} } func (x *UpdateVReplicationWorkflowsResponse) GetResult() *query.QueryResult { @@ -7072,7 +7127,7 @@ type ResetSequencesRequest struct { func (x *ResetSequencesRequest) Reset() { *x = ResetSequencesRequest{} - mi := &file_tabletmanagerdata_proto_msgTypes[136] + mi := &file_tabletmanagerdata_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7084,7 +7139,7 @@ func (x *ResetSequencesRequest) String() string { func (*ResetSequencesRequest) ProtoMessage() {} func (x *ResetSequencesRequest) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[136] + mi := &file_tabletmanagerdata_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7097,7 +7152,7 @@ func (x *ResetSequencesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResetSequencesRequest.ProtoReflect.Descriptor instead. func (*ResetSequencesRequest) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{136} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{137} } func (x *ResetSequencesRequest) GetTables() []string { @@ -7115,7 +7170,7 @@ type ResetSequencesResponse struct { func (x *ResetSequencesResponse) Reset() { *x = ResetSequencesResponse{} - mi := &file_tabletmanagerdata_proto_msgTypes[137] + mi := &file_tabletmanagerdata_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7127,7 +7182,7 @@ func (x *ResetSequencesResponse) String() string { func (*ResetSequencesResponse) ProtoMessage() {} func (x *ResetSequencesResponse) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[137] + mi := &file_tabletmanagerdata_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7140,7 +7195,7 @@ func (x *ResetSequencesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResetSequencesResponse.ProtoReflect.Descriptor instead. func (*ResetSequencesResponse) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{137} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{138} } type CheckThrottlerRequest struct { @@ -7158,7 +7213,7 @@ type CheckThrottlerRequest struct { func (x *CheckThrottlerRequest) Reset() { *x = CheckThrottlerRequest{} - mi := &file_tabletmanagerdata_proto_msgTypes[138] + mi := &file_tabletmanagerdata_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7170,7 +7225,7 @@ func (x *CheckThrottlerRequest) String() string { func (*CheckThrottlerRequest) ProtoMessage() {} func (x *CheckThrottlerRequest) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[138] + mi := &file_tabletmanagerdata_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7183,7 +7238,7 @@ func (x *CheckThrottlerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckThrottlerRequest.ProtoReflect.Descriptor instead. func (*CheckThrottlerRequest) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{138} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{139} } func (x *CheckThrottlerRequest) GetAppName() string { @@ -7243,7 +7298,7 @@ type CheckThrottlerResponse struct { func (x *CheckThrottlerResponse) Reset() { *x = CheckThrottlerResponse{} - mi := &file_tabletmanagerdata_proto_msgTypes[139] + mi := &file_tabletmanagerdata_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7255,7 +7310,7 @@ func (x *CheckThrottlerResponse) String() string { func (*CheckThrottlerResponse) ProtoMessage() {} func (x *CheckThrottlerResponse) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[139] + mi := &file_tabletmanagerdata_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7268,7 +7323,7 @@ func (x *CheckThrottlerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckThrottlerResponse.ProtoReflect.Descriptor instead. func (*CheckThrottlerResponse) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{139} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{140} } func (x *CheckThrottlerResponse) GetValue() float64 { @@ -7342,7 +7397,7 @@ type GetThrottlerStatusRequest struct { func (x *GetThrottlerStatusRequest) Reset() { *x = GetThrottlerStatusRequest{} - mi := &file_tabletmanagerdata_proto_msgTypes[140] + mi := &file_tabletmanagerdata_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7354,7 +7409,7 @@ func (x *GetThrottlerStatusRequest) String() string { func (*GetThrottlerStatusRequest) ProtoMessage() {} func (x *GetThrottlerStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[140] + mi := &file_tabletmanagerdata_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7367,7 +7422,7 @@ func (x *GetThrottlerStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetThrottlerStatusRequest.ProtoReflect.Descriptor instead. func (*GetThrottlerStatusRequest) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{140} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{141} } type GetThrottlerStatusResponse struct { @@ -7415,7 +7470,7 @@ type GetThrottlerStatusResponse struct { func (x *GetThrottlerStatusResponse) Reset() { *x = GetThrottlerStatusResponse{} - mi := &file_tabletmanagerdata_proto_msgTypes[141] + mi := &file_tabletmanagerdata_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7427,7 +7482,7 @@ func (x *GetThrottlerStatusResponse) String() string { func (*GetThrottlerStatusResponse) ProtoMessage() {} func (x *GetThrottlerStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[141] + mi := &file_tabletmanagerdata_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7440,7 +7495,7 @@ func (x *GetThrottlerStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetThrottlerStatusResponse.ProtoReflect.Descriptor instead. func (*GetThrottlerStatusResponse) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{141} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{142} } func (x *GetThrottlerStatusResponse) GetTabletAlias() string { @@ -7580,7 +7635,7 @@ type ChangeTagsRequest struct { func (x *ChangeTagsRequest) Reset() { *x = ChangeTagsRequest{} - mi := &file_tabletmanagerdata_proto_msgTypes[142] + mi := &file_tabletmanagerdata_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7592,7 +7647,7 @@ func (x *ChangeTagsRequest) String() string { func (*ChangeTagsRequest) ProtoMessage() {} func (x *ChangeTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[142] + mi := &file_tabletmanagerdata_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7605,7 +7660,7 @@ func (x *ChangeTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeTagsRequest.ProtoReflect.Descriptor instead. func (*ChangeTagsRequest) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{142} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{143} } func (x *ChangeTagsRequest) GetTags() map[string]string { @@ -7632,7 +7687,7 @@ type ChangeTagsResponse struct { func (x *ChangeTagsResponse) Reset() { *x = ChangeTagsResponse{} - mi := &file_tabletmanagerdata_proto_msgTypes[143] + mi := &file_tabletmanagerdata_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7644,7 +7699,7 @@ func (x *ChangeTagsResponse) String() string { func (*ChangeTagsResponse) ProtoMessage() {} func (x *ChangeTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[143] + mi := &file_tabletmanagerdata_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7657,7 +7712,7 @@ func (x *ChangeTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeTagsResponse.ProtoReflect.Descriptor instead. func (*ChangeTagsResponse) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{143} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{144} } func (x *ChangeTagsResponse) GetTags() map[string]string { @@ -7690,7 +7745,7 @@ type ReadVReplicationWorkflowResponse_Stream struct { func (x *ReadVReplicationWorkflowResponse_Stream) Reset() { *x = ReadVReplicationWorkflowResponse_Stream{} - mi := &file_tabletmanagerdata_proto_msgTypes[149] + mi := &file_tabletmanagerdata_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7702,7 +7757,7 @@ func (x *ReadVReplicationWorkflowResponse_Stream) String() string { func (*ReadVReplicationWorkflowResponse_Stream) ProtoMessage() {} func (x *ReadVReplicationWorkflowResponse_Stream) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[149] + mi := &file_tabletmanagerdata_proto_msgTypes[150] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7839,7 +7894,7 @@ type CheckThrottlerResponse_Metric struct { func (x *CheckThrottlerResponse_Metric) Reset() { *x = CheckThrottlerResponse_Metric{} - mi := &file_tabletmanagerdata_proto_msgTypes[152] + mi := &file_tabletmanagerdata_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7851,7 +7906,7 @@ func (x *CheckThrottlerResponse_Metric) String() string { func (*CheckThrottlerResponse_Metric) ProtoMessage() {} func (x *CheckThrottlerResponse_Metric) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[152] + mi := &file_tabletmanagerdata_proto_msgTypes[153] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7864,7 +7919,7 @@ func (x *CheckThrottlerResponse_Metric) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckThrottlerResponse_Metric.ProtoReflect.Descriptor instead. func (*CheckThrottlerResponse_Metric) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{139, 0} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{140, 0} } func (x *CheckThrottlerResponse_Metric) GetName() string { @@ -7927,7 +7982,7 @@ type GetThrottlerStatusResponse_MetricResult struct { func (x *GetThrottlerStatusResponse_MetricResult) Reset() { *x = GetThrottlerStatusResponse_MetricResult{} - mi := &file_tabletmanagerdata_proto_msgTypes[154] + mi := &file_tabletmanagerdata_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7939,7 +7994,7 @@ func (x *GetThrottlerStatusResponse_MetricResult) String() string { func (*GetThrottlerStatusResponse_MetricResult) ProtoMessage() {} func (x *GetThrottlerStatusResponse_MetricResult) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[154] + mi := &file_tabletmanagerdata_proto_msgTypes[155] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7952,7 +8007,7 @@ func (x *GetThrottlerStatusResponse_MetricResult) ProtoReflect() protoreflect.Me // Deprecated: Use GetThrottlerStatusResponse_MetricResult.ProtoReflect.Descriptor instead. func (*GetThrottlerStatusResponse_MetricResult) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{141, 0} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{142, 0} } func (x *GetThrottlerStatusResponse_MetricResult) GetValue() float64 { @@ -7980,7 +8035,7 @@ type GetThrottlerStatusResponse_MetricHealth struct { func (x *GetThrottlerStatusResponse_MetricHealth) Reset() { *x = GetThrottlerStatusResponse_MetricHealth{} - mi := &file_tabletmanagerdata_proto_msgTypes[157] + mi := &file_tabletmanagerdata_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7992,7 +8047,7 @@ func (x *GetThrottlerStatusResponse_MetricHealth) String() string { func (*GetThrottlerStatusResponse_MetricHealth) ProtoMessage() {} func (x *GetThrottlerStatusResponse_MetricHealth) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[157] + mi := &file_tabletmanagerdata_proto_msgTypes[158] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8005,7 +8060,7 @@ func (x *GetThrottlerStatusResponse_MetricHealth) ProtoReflect() protoreflect.Me // Deprecated: Use GetThrottlerStatusResponse_MetricHealth.ProtoReflect.Descriptor instead. func (*GetThrottlerStatusResponse_MetricHealth) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{141, 3} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{142, 3} } func (x *GetThrottlerStatusResponse_MetricHealth) GetLastHealthyAt() *vttime.Time { @@ -8034,7 +8089,7 @@ type GetThrottlerStatusResponse_RecentApp struct { func (x *GetThrottlerStatusResponse_RecentApp) Reset() { *x = GetThrottlerStatusResponse_RecentApp{} - mi := &file_tabletmanagerdata_proto_msgTypes[161] + mi := &file_tabletmanagerdata_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8046,7 +8101,7 @@ func (x *GetThrottlerStatusResponse_RecentApp) String() string { func (*GetThrottlerStatusResponse_RecentApp) ProtoMessage() {} func (x *GetThrottlerStatusResponse_RecentApp) ProtoReflect() protoreflect.Message { - mi := &file_tabletmanagerdata_proto_msgTypes[161] + mi := &file_tabletmanagerdata_proto_msgTypes[162] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8059,7 +8114,7 @@ func (x *GetThrottlerStatusResponse_RecentApp) ProtoReflect() protoreflect.Messa // Deprecated: Use GetThrottlerStatusResponse_RecentApp.ProtoReflect.Descriptor instead. func (*GetThrottlerStatusResponse_RecentApp) Descriptor() ([]byte, []int) { - return file_tabletmanagerdata_proto_rawDescGZIP(), []int{141, 7} + return file_tabletmanagerdata_proto_rawDescGZIP(), []int{142, 7} } func (x *GetThrottlerStatusResponse_RecentApp) GetCheckedAt() *vttime.Time { @@ -8432,351 +8487,242 @@ var file_tabletmanagerdata_proto_rawDesc = []byte{ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x73, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x73, 0x74, 0x22, 0x4c, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, - 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, 0x16, 0x0a, 0x14, 0x50, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x4f, 0x0a, 0x15, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x18, 0x0a, 0x16, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x35, 0x0a, 0x17, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x34, 0x0a, 0x16, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, 0x0a, 0x17, 0x57, 0x61, 0x69, 0x74, 0x46, - 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x19, 0x0a, 0x17, - 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0x0a, 0x1d, 0x53, 0x74, 0x6f, 0x70, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, - 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x77, 0x61, 0x69, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x3c, 0x0a, 0x1e, 0x53, 0x74, 0x6f, 0x70, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x35, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x1a, 0x0a, 0x18, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x21, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x74, 0x69, - 0x6c, 0x41, 0x66, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x61, 0x69, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0b, 0x77, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x24, 0x0a, 0x22, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x41, 0x66, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2b, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x61, 0x64, 0x64, 0x72, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x0a, 0x17, - 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x46, 0x0a, - 0x18, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x65, - 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x4b, 0x0a, 0x1d, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x20, 0x0a, 0x1e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, - 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, - 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x31, 0x0a, 0x13, 0x49, 0x6e, 0x69, 0x74, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xd8, 0x01, 0x0a, 0x1e, 0x50, 0x6f, - 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4a, 0x6f, - 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, - 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x4e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x0a, 0x1e, 0x52, 0x65, 0x61, 0x64, 0x52, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x39, 0x0a, 0x1f, 0x52, 0x65, 0x61, - 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x22, 0xba, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, - 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x4e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, - 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, - 0x63, 0x22, 0x15, 0x0a, 0x13, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, 0x6d, 0x6f, - 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x64, 0x0a, 0x15, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x22, 0x16, 0x0a, 0x14, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, 0x0a, 0x15, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x36, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x36, 0x0a, 0x18, 0x55, 0x6e, 0x64, 0x6f, 0x44, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x1b, - 0x0a, 0x19, 0x55, 0x6e, 0x64, 0x6f, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x24, 0x0a, 0x22, 0x52, - 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x13, 0x0a, 0x11, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x12, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, - 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x22, 0x9c, 0x02, 0x0a, 0x1b, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, - 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, - 0x63, 0x12, 0x2d, 0x0a, 0x12, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x68, - 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x22, 0x1e, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x4b, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, - 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0x1d, 0x0a, - 0x1b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x22, - 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, - 0x6e, 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x24, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x92, 0x01, 0x0a, - 0x23, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x6e, 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x72, - 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x4a, 0x04, 0x08, 0x01, 0x10, - 0x02, 0x22, 0x33, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, - 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, - 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x34, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe7, 0x01, 0x0a, - 0x0d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, - 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, - 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, - 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x6f, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x70, 0x67, 0x72, 0x61, - 0x64, 0x65, 0x5f, 0x73, 0x61, 0x66, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, - 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x53, 0x61, 0x66, 0x65, 0x12, 0x28, 0x0a, 0x0d, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, - 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xfe, - 0x01, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0b, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, - 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, - 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, - 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x22, - 0x41, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, - 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x22, 0xee, 0x04, 0x0a, 0x21, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x3d, 0x0a, 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0c, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x12, 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, - 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, - 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, - 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, - 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, - 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0x50, 0x0a, 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xda, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x60, 0x0a, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, - 0x65, 0x1a, 0x3f, 0x0a, 0x11, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x0a, - 0x21, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x50, - 0x0a, 0x22, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x22, 0x21, 0x0a, 0x1f, 0x48, 0x61, 0x73, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x20, 0x48, 0x61, 0x73, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x68, 0x61, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x68, 0x61, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x20, 0x52, 0x65, - 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, - 0x0a, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x64, 0x73, 0x12, - 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x4c, 0x0a, 0x0e, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x69, 0x6e, 0x63, - 0x6c, 0x75, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x5f, 0x66, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, - 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x46, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x21, - 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x73, 0x22, 0x3d, 0x0a, 0x1f, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x22, 0xe7, 0x0a, 0x0a, 0x20, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, + 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x35, 0x0a, 0x17, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x50, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x34, 0x0a, 0x16, 0x57, 0x61, + 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x19, 0x0a, 0x17, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x53, + 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x5e, 0x0a, 0x1d, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, + 0x0c, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x22, 0x3c, 0x0a, 0x1e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x35, + 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, + 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, + 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x1a, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x62, 0x0a, 0x21, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x41, 0x66, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x24, 0x0a, 0x22, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x41, 0x66, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x2b, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x22, 0x19, + 0x0a, 0x17, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x73, + 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x0a, 0x17, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x46, 0x0a, 0x18, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x4b, + 0x0a, 0x1d, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, + 0x69, 0x74, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x0a, 0x1e, 0x56, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x46, + 0x6f, 0x72, 0x50, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x0a, + 0x12, 0x49, 0x6e, 0x69, 0x74, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, + 0x31, 0x0a, 0x13, 0x49, 0x6e, 0x69, 0x74, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0xd8, 0x01, 0x0a, 0x1e, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, + 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x73, 0x12, 0x1f, 0x0a, + 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, + 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0c, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x21, 0x0a, + 0x1f, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x20, 0x0a, 0x1e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x39, 0x0a, 0x1f, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0xba, 0x01, + 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x15, 0x0a, 0x13, 0x49, 0x6e, + 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x64, 0x0a, 0x15, 0x44, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, + 0x36, 0x0a, 0x18, 0x55, 0x6e, 0x64, 0x6f, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, + 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, + 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x1b, 0x0a, 0x19, 0x55, 0x6e, 0x64, 0x6f, 0x44, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, + 0x61, 0x73, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x50, + 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x23, 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x24, 0x0a, 0x22, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x0a, 0x11, 0x46, 0x75, + 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x49, 0x0a, 0x12, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x9c, 0x02, 0x0a, 0x1b, 0x53, + 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, + 0x73, 0x12, 0x36, 0x0a, 0x17, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x15, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, + 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x2d, 0x0a, 0x12, 0x68, 0x65, + 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, + 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x1e, 0x0a, 0x1c, 0x53, 0x65, 0x74, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x0a, 0x1a, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x22, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x73, + 0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, + 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, + 0x52, 0x13, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x6b, 0x0a, 0x23, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x04, 0x08, 0x01, + 0x10, 0x02, 0x22, 0x33, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, + 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, + 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x34, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x6d, 0x6f, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe7, 0x01, + 0x0a, 0x0d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x6c, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x6f, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x70, 0x67, 0x72, + 0x61, 0x64, 0x65, 0x5f, 0x73, 0x61, 0x66, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x53, 0x61, 0x66, 0x65, 0x12, 0x28, 0x0a, 0x0d, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, + 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, + 0xfe, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0b, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, + 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, + 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, + 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, + 0x22, 0x41, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, + 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, + 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x22, 0xee, 0x04, 0x0a, 0x21, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x3d, 0x0a, 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0c, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, @@ -8787,470 +8733,585 @@ var file_tabletmanagerdata_proto_rawDesc = []byte{ 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x64, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, - 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x49, - 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, - 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, - 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, - 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, - 0x12, 0x54, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x07, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x73, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, - 0x69, 0x64, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, - 0x72, 0x69, 0x64, 0x65, 0x73, 0x1a, 0xc1, 0x04, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x2a, 0x0a, 0x03, 0x62, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x03, 0x62, 0x6c, 0x73, 0x12, 0x10, 0x0a, 0x03, - 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x12, 0x19, - 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x61, 0x78, - 0x5f, 0x74, 0x70, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x54, - 0x70, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x11, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, - 0x61, 0x67, 0x12, 0x2f, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x15, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x52, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, - 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x33, - 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, - 0x65, 0x61, 0x74, 0x12, 0x33, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x6f, - 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, 0x0a, - 0x26, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x27, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0xd7, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, - 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x64, 0x69, 0x66, 0x66, 0x5f, - 0x75, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x64, 0x69, 0x66, - 0x66, 0x55, 0x75, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x22, 0x6a, 0x0a, 0x0d, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x2a, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x76, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x76, 0x64, 0x69, 0x66, 0x66, 0x55, 0x75, 0x69, 0x64, 0x22, 0x79, 0x0a, 0x12, - 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x22, 0xce, 0x01, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, - 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x19, - 0x0a, 0x08, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x6b, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, - 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x61, 0x78, - 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x72, 0x6f, - 0x77, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x72, - 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x17, 0x72, 0x6f, 0x77, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x72, - 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x41, 0x74, 0x22, 0x8d, 0x03, 0x0a, 0x10, 0x56, 0x44, 0x69, - 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, - 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, - 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, - 0x65, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x70, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x50, 0x63, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, - 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, - 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x2c, 0x0a, - 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, - 0x61, 0x78, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x44, 0x69, 0x66, 0x66, 0x53, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x22, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, 0x74, - 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x61, 0x75, - 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0xf2, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, - 0x66, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x70, 0x69, 0x63, - 0x6b, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, 0x65, - 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x72, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6f, 0x72, 0x65, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x4c, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, - 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xed, 0x04, - 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x65, 0x12, 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, + 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, + 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, + 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x50, 0x0a, 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xda, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x60, 0x0a, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, + 0x7a, 0x65, 0x1a, 0x3f, 0x0a, 0x11, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, + 0x0a, 0x21, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, - 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x71, - 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x48, 0x00, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x88, 0x01, - 0x01, 0x12, 0x33, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, - 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x05, 0x6f, 0x6e, - 0x44, 0x64, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, + 0x50, 0x0a, 0x22, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0x21, 0x0a, 0x1f, 0x48, 0x61, 0x73, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x20, 0x48, 0x61, 0x73, 0x56, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x68, 0x61, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x68, 0x61, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x20, 0x52, + 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x64, 0x73, + 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x4c, 0x0a, + 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x02, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x74, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0e, + 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x46, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x22, 0x76, 0x0a, + 0x21, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0x3d, 0x0a, 0x1f, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, - 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x1a, 0x42, - 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x42, 0x1e, 0x0a, 0x1c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x42, 0x08, 0x0a, - 0x06, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0x50, 0x0a, - 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0xd6, 0x02, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x5f, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, - 0x6c, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, - 0x0c, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, - 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x5f, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x23, 0x55, 0x70, 0x64, 0x61, + 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x22, 0xe7, 0x0a, 0x0a, 0x20, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, + 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, + 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, + 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, + 0x73, 0x12, 0x54, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x0b, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x07, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x73, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, + 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x1a, 0xc1, 0x04, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x2a, 0x0a, 0x03, 0x62, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x03, 0x62, 0x6c, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x12, + 0x19, 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x61, + 0x78, 0x5f, 0x74, 0x70, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, + 0x54, 0x70, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x11, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4c, 0x61, 0x67, 0x12, 0x2f, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x15, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x52, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, + 0x33, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, + 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, + 0x62, 0x65, 0x61, 0x74, 0x12, 0x33, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, + 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, + 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, + 0x0a, 0x26, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x27, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0xd7, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x64, 0x69, 0x66, 0x66, + 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x64, 0x69, + 0x66, 0x66, 0x55, 0x75, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x6a, 0x0a, 0x0d, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x76, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x76, 0x64, 0x69, 0x66, 0x66, 0x55, 0x75, 0x69, 0x64, 0x22, 0x79, 0x0a, + 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x22, 0xce, 0x01, 0x0a, 0x12, 0x56, 0x44, 0x69, + 0x66, 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x19, 0x0a, 0x08, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x6b, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x61, + 0x78, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x72, + 0x6f, 0x77, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, + 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x17, 0x72, 0x6f, 0x77, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, + 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x41, 0x74, 0x22, 0x8d, 0x03, 0x0a, 0x10, 0x56, 0x44, + 0x69, 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, + 0x65, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, + 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x70, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x50, 0x63, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, + 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, + 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x2c, + 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, + 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x44, 0x69, 0x66, 0x66, 0x53, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x22, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, + 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x61, + 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0xf2, 0x01, 0x0a, 0x0c, 0x56, 0x44, + 0x69, 0x66, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x70, 0x69, + 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, + 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x70, 0x69, 0x63, 0x6b, 0x65, + 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6f, 0x72, 0x65, + 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x4c, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, + 0x66, 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7a, + 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, + 0x50, 0x4b, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2f, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x88, 0x01, 0x01, 0x42, + 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xaa, 0x05, 0x0a, 0x21, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x71, 0x0a, 0x1b, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, + 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x33, + 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x6e, 0x44, 0x44, + 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, + 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x02, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x74, 0x0a, + 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, + 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x52, - 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, - 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc6, 0x01, 0x0a, 0x15, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, - 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, - 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, - 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x10, 0x6f, 0x6b, 0x5f, - 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6f, 0x6b, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, - 0x74, 0x73, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x52, 0x15, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, - 0xf6, 0x05, 0x0a, 0x16, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, - 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, - 0x6c, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x07, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x61, - 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, - 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x43, 0x6f, 0x64, 0x65, 0x1a, 0xf0, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, - 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, - 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x52, 0x0a, - 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, + 0x01, 0x01, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, + 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x1e, 0x0a, 0x1c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x6e, 0x5f, 0x64, 0x64, + 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x50, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xd6, 0x02, 0x0a, 0x22, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, + 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x88, 0x01, + 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, + 0x12, 0x28, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x0c, 0x73, 0x74, 0x6f, 0x70, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x23, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xc6, 0x01, 0x0a, 0x15, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, + 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, + 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, + 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x72, + 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, + 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, + 0x61, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x10, 0x6f, 0x6b, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, + 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6f, + 0x6b, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x05, + 0x10, 0x06, 0x52, 0x15, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xf6, 0x05, 0x0a, 0x16, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, + 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, + 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, + 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x07, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, - 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, - 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x6c, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x0b, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9b, 0x10, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, - 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, - 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, - 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, - 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6f, 0x70, 0x65, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, - 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x12, 0x28, 0x0a, - 0x10, 0x6c, 0x61, 0x67, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6c, 0x61, 0x67, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, - 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x73, 0x5f, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x55, 0x73, 0x65, 0x64, 0x41, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x12, 0x73, 0x0a, 0x12, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, + 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, + 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0xf0, + 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x70, 0x0a, 0x11, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x18, 0x0d, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, - 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, - 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x12, 0x67, 0x0a, 0x0e, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x0e, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x12, 0x67, 0x0a, 0x0e, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, - 0x61, 0x70, 0x70, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, - 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x12, 0x74, 0x0a, 0x13, 0x61, - 0x70, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, + 0x03, 0x1a, 0x6c, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, + 0x64, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x9b, 0x10, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, + 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, + 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, + 0x44, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x67, 0x5f, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x6c, 0x61, 0x67, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, + 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x74, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x3c, + 0x0a, 0x1b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x75, 0x73, + 0x65, 0x64, 0x5f, 0x61, 0x73, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x17, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x55, + 0x73, 0x65, 0x64, 0x41, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x73, 0x0a, 0x12, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, - 0x61, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x63, - 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x5e, 0x0a, 0x0b, - 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x80, 0x01, 0x0a, 0x16, 0x41, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x12, 0x70, 0x0a, 0x11, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x68, 0x72, 0x65, + 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x10, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, + 0x6c, 0x64, 0x73, 0x12, 0x67, 0x0a, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x68, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x67, 0x0a, 0x0e, + 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0f, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x43, 0x0a, 0x15, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x1a, 0x81, 0x01, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x12, 0x34, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x79, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x79, 0x41, 0x74, 0x12, 0x3b, 0x0a, 0x1a, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x79, 0x1a, 0x7c, 0x0a, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, + 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x64, 0x41, 0x70, 0x70, 0x73, 0x12, 0x74, 0x0a, 0x13, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x10, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, + 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x61, 0x70, 0x70, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, + 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x5e, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, + 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x5c, 0x0a, 0x12, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, - 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, - 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x1a, 0x44, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x92, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x63, 0x65, 0x6e, - 0x74, 0x41, 0x70, 0x70, 0x12, 0x2b, 0x0a, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x43, 0x6f, 0x64, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x76, 0x0a, 0x0f, 0x52, - 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x6e, + 0x74, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, + 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x1a, 0x80, 0x01, 0x0a, 0x16, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, + 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x43, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, + 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x37, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, - 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xaa, 0x01, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, - 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x04, 0x74, 0x61, 0x67, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x61, - 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x81, 0x01, 0x0a, 0x0c, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x34, 0x0a, 0x0f, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x5f, 0x61, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x41, + 0x74, 0x12, 0x3b, 0x0a, 0x1a, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x73, 0x69, 0x6e, + 0x63, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x53, 0x69, + 0x6e, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x1a, 0x7c, + 0x0a, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5c, 0x0a, 0x12, + 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, + 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, 0x0a, 0x16, 0x41, 0x70, + 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x92, 0x01, 0x0a, 0x12, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x67, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, - 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x3e, 0x0a, 0x19, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, - 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, - 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, 0x83, 0x01, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, - 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, - 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x50, 0x50, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, - 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4d, - 0x45, 0x54, 0x52, 0x49, 0x43, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, - 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x42, 0x30, 0x5a, 0x2e, 0x76, - 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, - 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x1a, 0x92, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x12, 0x2b, + 0x0a, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x52, 0x09, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x12, 0x52, 0x0a, 0x0d, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, + 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x4a, + 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x76, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, + 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, + 0x70, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xaa, 0x01, + 0x0a, 0x11, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x92, 0x01, 0x0a, 0x12, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x43, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, + 0x3e, 0x0a, 0x19, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x07, 0x0a, 0x03, + 0x41, 0x4e, 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, + 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, + 0x83, 0x01, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0d, + 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, + 0x02, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, + 0x4c, 0x44, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, + 0x0a, 0x41, 0x50, 0x50, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, + 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x10, + 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x10, 0x05, 0x42, 0x30, 0x5a, 0x2e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, + 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -9266,7 +9327,7 @@ func file_tabletmanagerdata_proto_rawDescGZIP() []byte { } var file_tabletmanagerdata_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_tabletmanagerdata_proto_msgTypes = make([]protoimpl.MessageInfo, 165) +var file_tabletmanagerdata_proto_msgTypes = make([]protoimpl.MessageInfo, 166) var file_tabletmanagerdata_proto_goTypes = []any{ (TabletSelectionPreference)(0), // 0: tabletmanagerdata.TabletSelectionPreference (CheckThrottlerResponseCode)(0), // 1: tabletmanagerdata.CheckThrottlerResponseCode @@ -9402,163 +9463,166 @@ var file_tabletmanagerdata_proto_goTypes = []any{ (*VDiffReportOptions)(nil), // 131: tabletmanagerdata.VDiffReportOptions (*VDiffCoreOptions)(nil), // 132: tabletmanagerdata.VDiffCoreOptions (*VDiffOptions)(nil), // 133: tabletmanagerdata.VDiffOptions - (*UpdateVReplicationWorkflowRequest)(nil), // 134: tabletmanagerdata.UpdateVReplicationWorkflowRequest - (*UpdateVReplicationWorkflowResponse)(nil), // 135: tabletmanagerdata.UpdateVReplicationWorkflowResponse - (*UpdateVReplicationWorkflowsRequest)(nil), // 136: tabletmanagerdata.UpdateVReplicationWorkflowsRequest - (*UpdateVReplicationWorkflowsResponse)(nil), // 137: tabletmanagerdata.UpdateVReplicationWorkflowsResponse - (*ResetSequencesRequest)(nil), // 138: tabletmanagerdata.ResetSequencesRequest - (*ResetSequencesResponse)(nil), // 139: tabletmanagerdata.ResetSequencesResponse - (*CheckThrottlerRequest)(nil), // 140: tabletmanagerdata.CheckThrottlerRequest - (*CheckThrottlerResponse)(nil), // 141: tabletmanagerdata.CheckThrottlerResponse - (*GetThrottlerStatusRequest)(nil), // 142: tabletmanagerdata.GetThrottlerStatusRequest - (*GetThrottlerStatusResponse)(nil), // 143: tabletmanagerdata.GetThrottlerStatusResponse - (*ChangeTagsRequest)(nil), // 144: tabletmanagerdata.ChangeTagsRequest - (*ChangeTagsResponse)(nil), // 145: tabletmanagerdata.ChangeTagsResponse - nil, // 146: tabletmanagerdata.UserPermission.PrivilegesEntry - nil, // 147: tabletmanagerdata.DbPermission.PrivilegesEntry - nil, // 148: tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry - nil, // 149: tabletmanagerdata.GetGlobalStatusVarsResponse.StatusValuesEntry - nil, // 150: tabletmanagerdata.DeleteTableDataRequest.TableFiltersEntry - (*ReadVReplicationWorkflowResponse_Stream)(nil), // 151: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream - nil, // 152: tabletmanagerdata.ReadVReplicationWorkflowResponse.ConfigOverridesEntry - nil, // 153: tabletmanagerdata.UpdateVReplicationWorkflowRequest.ConfigOverridesEntry - (*CheckThrottlerResponse_Metric)(nil), // 154: tabletmanagerdata.CheckThrottlerResponse.Metric - nil, // 155: tabletmanagerdata.CheckThrottlerResponse.MetricsEntry - (*GetThrottlerStatusResponse_MetricResult)(nil), // 156: tabletmanagerdata.GetThrottlerStatusResponse.MetricResult - nil, // 157: tabletmanagerdata.GetThrottlerStatusResponse.AggregatedMetricsEntry - nil, // 158: tabletmanagerdata.GetThrottlerStatusResponse.MetricThresholdsEntry - (*GetThrottlerStatusResponse_MetricHealth)(nil), // 159: tabletmanagerdata.GetThrottlerStatusResponse.MetricHealth - nil, // 160: tabletmanagerdata.GetThrottlerStatusResponse.MetricsHealthEntry - nil, // 161: tabletmanagerdata.GetThrottlerStatusResponse.ThrottledAppsEntry - nil, // 162: tabletmanagerdata.GetThrottlerStatusResponse.AppCheckedMetricsEntry - (*GetThrottlerStatusResponse_RecentApp)(nil), // 163: tabletmanagerdata.GetThrottlerStatusResponse.RecentApp - nil, // 164: tabletmanagerdata.GetThrottlerStatusResponse.RecentAppsEntry - nil, // 165: tabletmanagerdata.ChangeTagsRequest.TagsEntry - nil, // 166: tabletmanagerdata.ChangeTagsResponse.TagsEntry - (*query.Field)(nil), // 167: query.Field - (topodata.TabletType)(0), // 168: topodata.TabletType - (*vtrpc.CallerID)(nil), // 169: vtrpc.CallerID - (*query.QueryResult)(nil), // 170: query.QueryResult - (*query.TransactionMetadata)(nil), // 171: query.TransactionMetadata - (*mysqlctl.HostMetricsResponse)(nil), // 172: mysqlctl.HostMetricsResponse - (*replicationdata.Status)(nil), // 173: replicationdata.Status - (*replicationdata.PrimaryStatus)(nil), // 174: replicationdata.PrimaryStatus - (*topodata.TabletAlias)(nil), // 175: topodata.TabletAlias - (*replicationdata.FullStatus)(nil), // 176: replicationdata.FullStatus - (replicationdata.StopReplicationMode)(0), // 177: replicationdata.StopReplicationMode - (*replicationdata.StopReplicationStatus)(nil), // 178: replicationdata.StopReplicationStatus - (*logutil.Event)(nil), // 179: logutil.Event - (*vttime.Time)(nil), // 180: vttime.Time - (*binlogdata.BinlogSource)(nil), // 181: binlogdata.BinlogSource - (binlogdata.VReplicationWorkflowType)(0), // 182: binlogdata.VReplicationWorkflowType - (binlogdata.VReplicationWorkflowSubType)(0), // 183: binlogdata.VReplicationWorkflowSubType - (binlogdata.VReplicationWorkflowState)(0), // 184: binlogdata.VReplicationWorkflowState - (binlogdata.OnDDLAction)(0), // 185: binlogdata.OnDDLAction - (*topodata.ThrottledAppRule)(nil), // 186: topodata.ThrottledAppRule + (*VDiffTableLastPK)(nil), // 134: tabletmanagerdata.VDiffTableLastPK + (*UpdateVReplicationWorkflowRequest)(nil), // 135: tabletmanagerdata.UpdateVReplicationWorkflowRequest + (*UpdateVReplicationWorkflowResponse)(nil), // 136: tabletmanagerdata.UpdateVReplicationWorkflowResponse + (*UpdateVReplicationWorkflowsRequest)(nil), // 137: tabletmanagerdata.UpdateVReplicationWorkflowsRequest + (*UpdateVReplicationWorkflowsResponse)(nil), // 138: tabletmanagerdata.UpdateVReplicationWorkflowsResponse + (*ResetSequencesRequest)(nil), // 139: tabletmanagerdata.ResetSequencesRequest + (*ResetSequencesResponse)(nil), // 140: tabletmanagerdata.ResetSequencesResponse + (*CheckThrottlerRequest)(nil), // 141: tabletmanagerdata.CheckThrottlerRequest + (*CheckThrottlerResponse)(nil), // 142: tabletmanagerdata.CheckThrottlerResponse + (*GetThrottlerStatusRequest)(nil), // 143: tabletmanagerdata.GetThrottlerStatusRequest + (*GetThrottlerStatusResponse)(nil), // 144: tabletmanagerdata.GetThrottlerStatusResponse + (*ChangeTagsRequest)(nil), // 145: tabletmanagerdata.ChangeTagsRequest + (*ChangeTagsResponse)(nil), // 146: tabletmanagerdata.ChangeTagsResponse + nil, // 147: tabletmanagerdata.UserPermission.PrivilegesEntry + nil, // 148: tabletmanagerdata.DbPermission.PrivilegesEntry + nil, // 149: tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry + nil, // 150: tabletmanagerdata.GetGlobalStatusVarsResponse.StatusValuesEntry + nil, // 151: tabletmanagerdata.DeleteTableDataRequest.TableFiltersEntry + (*ReadVReplicationWorkflowResponse_Stream)(nil), // 152: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream + nil, // 153: tabletmanagerdata.ReadVReplicationWorkflowResponse.ConfigOverridesEntry + nil, // 154: tabletmanagerdata.UpdateVReplicationWorkflowRequest.ConfigOverridesEntry + (*CheckThrottlerResponse_Metric)(nil), // 155: tabletmanagerdata.CheckThrottlerResponse.Metric + nil, // 156: tabletmanagerdata.CheckThrottlerResponse.MetricsEntry + (*GetThrottlerStatusResponse_MetricResult)(nil), // 157: tabletmanagerdata.GetThrottlerStatusResponse.MetricResult + nil, // 158: tabletmanagerdata.GetThrottlerStatusResponse.AggregatedMetricsEntry + nil, // 159: tabletmanagerdata.GetThrottlerStatusResponse.MetricThresholdsEntry + (*GetThrottlerStatusResponse_MetricHealth)(nil), // 160: tabletmanagerdata.GetThrottlerStatusResponse.MetricHealth + nil, // 161: tabletmanagerdata.GetThrottlerStatusResponse.MetricsHealthEntry + nil, // 162: tabletmanagerdata.GetThrottlerStatusResponse.ThrottledAppsEntry + nil, // 163: tabletmanagerdata.GetThrottlerStatusResponse.AppCheckedMetricsEntry + (*GetThrottlerStatusResponse_RecentApp)(nil), // 164: tabletmanagerdata.GetThrottlerStatusResponse.RecentApp + nil, // 165: tabletmanagerdata.GetThrottlerStatusResponse.RecentAppsEntry + nil, // 166: tabletmanagerdata.ChangeTagsRequest.TagsEntry + nil, // 167: tabletmanagerdata.ChangeTagsResponse.TagsEntry + (*query.Field)(nil), // 168: query.Field + (topodata.TabletType)(0), // 169: topodata.TabletType + (*vtrpc.CallerID)(nil), // 170: vtrpc.CallerID + (*query.QueryResult)(nil), // 171: query.QueryResult + (*query.TransactionMetadata)(nil), // 172: query.TransactionMetadata + (*mysqlctl.HostMetricsResponse)(nil), // 173: mysqlctl.HostMetricsResponse + (*replicationdata.Status)(nil), // 174: replicationdata.Status + (*replicationdata.PrimaryStatus)(nil), // 175: replicationdata.PrimaryStatus + (*topodata.TabletAlias)(nil), // 176: topodata.TabletAlias + (*replicationdata.FullStatus)(nil), // 177: replicationdata.FullStatus + (replicationdata.StopReplicationMode)(0), // 178: replicationdata.StopReplicationMode + (*replicationdata.StopReplicationStatus)(nil), // 179: replicationdata.StopReplicationStatus + (*logutil.Event)(nil), // 180: logutil.Event + (*vttime.Time)(nil), // 181: vttime.Time + (*binlogdata.BinlogSource)(nil), // 182: binlogdata.BinlogSource + (binlogdata.VReplicationWorkflowType)(0), // 183: binlogdata.VReplicationWorkflowType + (binlogdata.VReplicationWorkflowSubType)(0), // 184: binlogdata.VReplicationWorkflowSubType + (binlogdata.VReplicationWorkflowState)(0), // 185: binlogdata.VReplicationWorkflowState + (binlogdata.OnDDLAction)(0), // 186: binlogdata.OnDDLAction + (*topodata.ThrottledAppRule)(nil), // 187: topodata.ThrottledAppRule } var file_tabletmanagerdata_proto_depIdxs = []int32{ - 167, // 0: tabletmanagerdata.TableDefinition.fields:type_name -> query.Field + 168, // 0: tabletmanagerdata.TableDefinition.fields:type_name -> query.Field 2, // 1: tabletmanagerdata.SchemaDefinition.table_definitions:type_name -> tabletmanagerdata.TableDefinition 3, // 2: tabletmanagerdata.SchemaChangeResult.before_schema:type_name -> tabletmanagerdata.SchemaDefinition 3, // 3: tabletmanagerdata.SchemaChangeResult.after_schema:type_name -> tabletmanagerdata.SchemaDefinition - 146, // 4: tabletmanagerdata.UserPermission.privileges:type_name -> tabletmanagerdata.UserPermission.PrivilegesEntry - 147, // 5: tabletmanagerdata.DbPermission.privileges:type_name -> tabletmanagerdata.DbPermission.PrivilegesEntry + 147, // 4: tabletmanagerdata.UserPermission.privileges:type_name -> tabletmanagerdata.UserPermission.PrivilegesEntry + 148, // 5: tabletmanagerdata.DbPermission.privileges:type_name -> tabletmanagerdata.DbPermission.PrivilegesEntry 5, // 6: tabletmanagerdata.Permissions.user_permissions:type_name -> tabletmanagerdata.UserPermission 6, // 7: tabletmanagerdata.Permissions.db_permissions:type_name -> tabletmanagerdata.DbPermission - 148, // 8: tabletmanagerdata.ExecuteHookRequest.extra_env:type_name -> tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry + 149, // 8: tabletmanagerdata.ExecuteHookRequest.extra_env:type_name -> tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry 3, // 9: tabletmanagerdata.GetSchemaResponse.schema_definition:type_name -> tabletmanagerdata.SchemaDefinition 7, // 10: tabletmanagerdata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions - 149, // 11: tabletmanagerdata.GetGlobalStatusVarsResponse.status_values:type_name -> tabletmanagerdata.GetGlobalStatusVarsResponse.StatusValuesEntry - 168, // 12: tabletmanagerdata.ChangeTypeRequest.tablet_type:type_name -> topodata.TabletType + 150, // 11: tabletmanagerdata.GetGlobalStatusVarsResponse.status_values:type_name -> tabletmanagerdata.GetGlobalStatusVarsResponse.StatusValuesEntry + 169, // 12: tabletmanagerdata.ChangeTypeRequest.tablet_type:type_name -> topodata.TabletType 4, // 13: tabletmanagerdata.PreflightSchemaResponse.change_results:type_name -> tabletmanagerdata.SchemaChangeResult 3, // 14: tabletmanagerdata.ApplySchemaRequest.before_schema:type_name -> tabletmanagerdata.SchemaDefinition 3, // 15: tabletmanagerdata.ApplySchemaRequest.after_schema:type_name -> tabletmanagerdata.SchemaDefinition 3, // 16: tabletmanagerdata.ApplySchemaResponse.before_schema:type_name -> tabletmanagerdata.SchemaDefinition 3, // 17: tabletmanagerdata.ApplySchemaResponse.after_schema:type_name -> tabletmanagerdata.SchemaDefinition - 169, // 18: tabletmanagerdata.ExecuteQueryRequest.caller_id:type_name -> vtrpc.CallerID - 170, // 19: tabletmanagerdata.ExecuteQueryResponse.result:type_name -> query.QueryResult - 170, // 20: tabletmanagerdata.ExecuteFetchAsDbaResponse.result:type_name -> query.QueryResult - 170, // 21: tabletmanagerdata.ExecuteMultiFetchAsDbaResponse.results:type_name -> query.QueryResult - 170, // 22: tabletmanagerdata.ExecuteFetchAsAllPrivsResponse.result:type_name -> query.QueryResult - 170, // 23: tabletmanagerdata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult - 171, // 24: tabletmanagerdata.GetUnresolvedTransactionsResponse.transactions:type_name -> query.TransactionMetadata - 171, // 25: tabletmanagerdata.ReadTransactionResponse.transaction:type_name -> query.TransactionMetadata - 172, // 26: tabletmanagerdata.MysqlHostMetricsResponse.HostMetrics:type_name -> mysqlctl.HostMetricsResponse - 173, // 27: tabletmanagerdata.ReplicationStatusResponse.status:type_name -> replicationdata.Status - 174, // 28: tabletmanagerdata.PrimaryStatusResponse.status:type_name -> replicationdata.PrimaryStatus - 170, // 29: tabletmanagerdata.VReplicationExecResponse.result:type_name -> query.QueryResult - 175, // 30: tabletmanagerdata.PopulateReparentJournalRequest.primary_alias:type_name -> topodata.TabletAlias - 175, // 31: tabletmanagerdata.InitReplicaRequest.parent:type_name -> topodata.TabletAlias - 174, // 32: tabletmanagerdata.DemotePrimaryResponse.primary_status:type_name -> replicationdata.PrimaryStatus - 176, // 33: tabletmanagerdata.FullStatusResponse.status:type_name -> replicationdata.FullStatus - 175, // 34: tabletmanagerdata.SetReplicationSourceRequest.parent:type_name -> topodata.TabletAlias - 175, // 35: tabletmanagerdata.ReplicaWasRestartedRequest.parent:type_name -> topodata.TabletAlias - 177, // 36: tabletmanagerdata.StopReplicationAndGetStatusRequest.stop_replication_mode:type_name -> replicationdata.StopReplicationMode - 178, // 37: tabletmanagerdata.StopReplicationAndGetStatusResponse.status:type_name -> replicationdata.StopReplicationStatus - 179, // 38: tabletmanagerdata.BackupResponse.event:type_name -> logutil.Event - 180, // 39: tabletmanagerdata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time - 180, // 40: tabletmanagerdata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time - 179, // 41: tabletmanagerdata.RestoreFromBackupResponse.event:type_name -> logutil.Event - 181, // 42: tabletmanagerdata.CreateVReplicationWorkflowRequest.binlog_source:type_name -> binlogdata.BinlogSource - 168, // 43: tabletmanagerdata.CreateVReplicationWorkflowRequest.tablet_types:type_name -> topodata.TabletType + 170, // 18: tabletmanagerdata.ExecuteQueryRequest.caller_id:type_name -> vtrpc.CallerID + 171, // 19: tabletmanagerdata.ExecuteQueryResponse.result:type_name -> query.QueryResult + 171, // 20: tabletmanagerdata.ExecuteFetchAsDbaResponse.result:type_name -> query.QueryResult + 171, // 21: tabletmanagerdata.ExecuteMultiFetchAsDbaResponse.results:type_name -> query.QueryResult + 171, // 22: tabletmanagerdata.ExecuteFetchAsAllPrivsResponse.result:type_name -> query.QueryResult + 171, // 23: tabletmanagerdata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult + 172, // 24: tabletmanagerdata.GetUnresolvedTransactionsResponse.transactions:type_name -> query.TransactionMetadata + 172, // 25: tabletmanagerdata.ReadTransactionResponse.transaction:type_name -> query.TransactionMetadata + 173, // 26: tabletmanagerdata.MysqlHostMetricsResponse.HostMetrics:type_name -> mysqlctl.HostMetricsResponse + 174, // 27: tabletmanagerdata.ReplicationStatusResponse.status:type_name -> replicationdata.Status + 175, // 28: tabletmanagerdata.PrimaryStatusResponse.status:type_name -> replicationdata.PrimaryStatus + 171, // 29: tabletmanagerdata.VReplicationExecResponse.result:type_name -> query.QueryResult + 176, // 30: tabletmanagerdata.PopulateReparentJournalRequest.primary_alias:type_name -> topodata.TabletAlias + 176, // 31: tabletmanagerdata.InitReplicaRequest.parent:type_name -> topodata.TabletAlias + 175, // 32: tabletmanagerdata.DemotePrimaryResponse.primary_status:type_name -> replicationdata.PrimaryStatus + 177, // 33: tabletmanagerdata.FullStatusResponse.status:type_name -> replicationdata.FullStatus + 176, // 34: tabletmanagerdata.SetReplicationSourceRequest.parent:type_name -> topodata.TabletAlias + 176, // 35: tabletmanagerdata.ReplicaWasRestartedRequest.parent:type_name -> topodata.TabletAlias + 178, // 36: tabletmanagerdata.StopReplicationAndGetStatusRequest.stop_replication_mode:type_name -> replicationdata.StopReplicationMode + 179, // 37: tabletmanagerdata.StopReplicationAndGetStatusResponse.status:type_name -> replicationdata.StopReplicationStatus + 180, // 38: tabletmanagerdata.BackupResponse.event:type_name -> logutil.Event + 181, // 39: tabletmanagerdata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time + 181, // 40: tabletmanagerdata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time + 180, // 41: tabletmanagerdata.RestoreFromBackupResponse.event:type_name -> logutil.Event + 182, // 42: tabletmanagerdata.CreateVReplicationWorkflowRequest.binlog_source:type_name -> binlogdata.BinlogSource + 169, // 43: tabletmanagerdata.CreateVReplicationWorkflowRequest.tablet_types:type_name -> topodata.TabletType 0, // 44: tabletmanagerdata.CreateVReplicationWorkflowRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 182, // 45: tabletmanagerdata.CreateVReplicationWorkflowRequest.workflow_type:type_name -> binlogdata.VReplicationWorkflowType - 183, // 46: tabletmanagerdata.CreateVReplicationWorkflowRequest.workflow_sub_type:type_name -> binlogdata.VReplicationWorkflowSubType - 170, // 47: tabletmanagerdata.CreateVReplicationWorkflowResponse.result:type_name -> query.QueryResult - 150, // 48: tabletmanagerdata.DeleteTableDataRequest.table_filters:type_name -> tabletmanagerdata.DeleteTableDataRequest.TableFiltersEntry - 170, // 49: tabletmanagerdata.DeleteVReplicationWorkflowResponse.result:type_name -> query.QueryResult - 184, // 50: tabletmanagerdata.ReadVReplicationWorkflowsRequest.include_states:type_name -> binlogdata.VReplicationWorkflowState - 184, // 51: tabletmanagerdata.ReadVReplicationWorkflowsRequest.exclude_states:type_name -> binlogdata.VReplicationWorkflowState + 183, // 45: tabletmanagerdata.CreateVReplicationWorkflowRequest.workflow_type:type_name -> binlogdata.VReplicationWorkflowType + 184, // 46: tabletmanagerdata.CreateVReplicationWorkflowRequest.workflow_sub_type:type_name -> binlogdata.VReplicationWorkflowSubType + 171, // 47: tabletmanagerdata.CreateVReplicationWorkflowResponse.result:type_name -> query.QueryResult + 151, // 48: tabletmanagerdata.DeleteTableDataRequest.table_filters:type_name -> tabletmanagerdata.DeleteTableDataRequest.TableFiltersEntry + 171, // 49: tabletmanagerdata.DeleteVReplicationWorkflowResponse.result:type_name -> query.QueryResult + 185, // 50: tabletmanagerdata.ReadVReplicationWorkflowsRequest.include_states:type_name -> binlogdata.VReplicationWorkflowState + 185, // 51: tabletmanagerdata.ReadVReplicationWorkflowsRequest.exclude_states:type_name -> binlogdata.VReplicationWorkflowState 125, // 52: tabletmanagerdata.ReadVReplicationWorkflowsResponse.workflows:type_name -> tabletmanagerdata.ReadVReplicationWorkflowResponse - 168, // 53: tabletmanagerdata.ReadVReplicationWorkflowResponse.tablet_types:type_name -> topodata.TabletType + 169, // 53: tabletmanagerdata.ReadVReplicationWorkflowResponse.tablet_types:type_name -> topodata.TabletType 0, // 54: tabletmanagerdata.ReadVReplicationWorkflowResponse.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 182, // 55: tabletmanagerdata.ReadVReplicationWorkflowResponse.workflow_type:type_name -> binlogdata.VReplicationWorkflowType - 183, // 56: tabletmanagerdata.ReadVReplicationWorkflowResponse.workflow_sub_type:type_name -> binlogdata.VReplicationWorkflowSubType - 151, // 57: tabletmanagerdata.ReadVReplicationWorkflowResponse.streams:type_name -> tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream - 152, // 58: tabletmanagerdata.ReadVReplicationWorkflowResponse.config_overrides:type_name -> tabletmanagerdata.ReadVReplicationWorkflowResponse.ConfigOverridesEntry + 183, // 55: tabletmanagerdata.ReadVReplicationWorkflowResponse.workflow_type:type_name -> binlogdata.VReplicationWorkflowType + 184, // 56: tabletmanagerdata.ReadVReplicationWorkflowResponse.workflow_sub_type:type_name -> binlogdata.VReplicationWorkflowSubType + 152, // 57: tabletmanagerdata.ReadVReplicationWorkflowResponse.streams:type_name -> tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream + 153, // 58: tabletmanagerdata.ReadVReplicationWorkflowResponse.config_overrides:type_name -> tabletmanagerdata.ReadVReplicationWorkflowResponse.ConfigOverridesEntry 133, // 59: tabletmanagerdata.VDiffRequest.options:type_name -> tabletmanagerdata.VDiffOptions - 170, // 60: tabletmanagerdata.VDiffResponse.output:type_name -> query.QueryResult + 171, // 60: tabletmanagerdata.VDiffResponse.output:type_name -> query.QueryResult 130, // 61: tabletmanagerdata.VDiffOptions.picker_options:type_name -> tabletmanagerdata.VDiffPickerOptions 132, // 62: tabletmanagerdata.VDiffOptions.core_options:type_name -> tabletmanagerdata.VDiffCoreOptions 131, // 63: tabletmanagerdata.VDiffOptions.report_options:type_name -> tabletmanagerdata.VDiffReportOptions - 168, // 64: tabletmanagerdata.UpdateVReplicationWorkflowRequest.tablet_types:type_name -> topodata.TabletType - 0, // 65: tabletmanagerdata.UpdateVReplicationWorkflowRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 185, // 66: tabletmanagerdata.UpdateVReplicationWorkflowRequest.on_ddl:type_name -> binlogdata.OnDDLAction - 184, // 67: tabletmanagerdata.UpdateVReplicationWorkflowRequest.state:type_name -> binlogdata.VReplicationWorkflowState - 153, // 68: tabletmanagerdata.UpdateVReplicationWorkflowRequest.config_overrides:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest.ConfigOverridesEntry - 170, // 69: tabletmanagerdata.UpdateVReplicationWorkflowResponse.result:type_name -> query.QueryResult - 184, // 70: tabletmanagerdata.UpdateVReplicationWorkflowsRequest.state:type_name -> binlogdata.VReplicationWorkflowState - 170, // 71: tabletmanagerdata.UpdateVReplicationWorkflowsResponse.result:type_name -> query.QueryResult - 155, // 72: tabletmanagerdata.CheckThrottlerResponse.metrics:type_name -> tabletmanagerdata.CheckThrottlerResponse.MetricsEntry - 1, // 73: tabletmanagerdata.CheckThrottlerResponse.response_code:type_name -> tabletmanagerdata.CheckThrottlerResponseCode - 157, // 74: tabletmanagerdata.GetThrottlerStatusResponse.aggregated_metrics:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.AggregatedMetricsEntry - 158, // 75: tabletmanagerdata.GetThrottlerStatusResponse.metric_thresholds:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricThresholdsEntry - 160, // 76: tabletmanagerdata.GetThrottlerStatusResponse.metrics_health:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricsHealthEntry - 161, // 77: tabletmanagerdata.GetThrottlerStatusResponse.throttled_apps:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.ThrottledAppsEntry - 162, // 78: tabletmanagerdata.GetThrottlerStatusResponse.app_checked_metrics:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.AppCheckedMetricsEntry - 164, // 79: tabletmanagerdata.GetThrottlerStatusResponse.recent_apps:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.RecentAppsEntry - 165, // 80: tabletmanagerdata.ChangeTagsRequest.tags:type_name -> tabletmanagerdata.ChangeTagsRequest.TagsEntry - 166, // 81: tabletmanagerdata.ChangeTagsResponse.tags:type_name -> tabletmanagerdata.ChangeTagsResponse.TagsEntry - 181, // 82: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.bls:type_name -> binlogdata.BinlogSource - 180, // 83: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.time_updated:type_name -> vttime.Time - 180, // 84: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.transaction_timestamp:type_name -> vttime.Time - 184, // 85: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.state:type_name -> binlogdata.VReplicationWorkflowState - 180, // 86: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.time_heartbeat:type_name -> vttime.Time - 180, // 87: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.time_throttled:type_name -> vttime.Time - 1, // 88: tabletmanagerdata.CheckThrottlerResponse.Metric.response_code:type_name -> tabletmanagerdata.CheckThrottlerResponseCode - 154, // 89: tabletmanagerdata.CheckThrottlerResponse.MetricsEntry.value:type_name -> tabletmanagerdata.CheckThrottlerResponse.Metric - 156, // 90: tabletmanagerdata.GetThrottlerStatusResponse.AggregatedMetricsEntry.value:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricResult - 180, // 91: tabletmanagerdata.GetThrottlerStatusResponse.MetricHealth.last_healthy_at:type_name -> vttime.Time - 159, // 92: tabletmanagerdata.GetThrottlerStatusResponse.MetricsHealthEntry.value:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricHealth - 186, // 93: tabletmanagerdata.GetThrottlerStatusResponse.ThrottledAppsEntry.value:type_name -> topodata.ThrottledAppRule - 180, // 94: tabletmanagerdata.GetThrottlerStatusResponse.RecentApp.checked_at:type_name -> vttime.Time - 1, // 95: tabletmanagerdata.GetThrottlerStatusResponse.RecentApp.response_code:type_name -> tabletmanagerdata.CheckThrottlerResponseCode - 163, // 96: tabletmanagerdata.GetThrottlerStatusResponse.RecentAppsEntry.value:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.RecentApp - 97, // [97:97] is the sub-list for method output_type - 97, // [97:97] is the sub-list for method input_type - 97, // [97:97] is the sub-list for extension type_name - 97, // [97:97] is the sub-list for extension extendee - 0, // [0:97] is the sub-list for field type_name + 171, // 64: tabletmanagerdata.VDiffTableLastPK.target:type_name -> query.QueryResult + 171, // 65: tabletmanagerdata.VDiffTableLastPK.source:type_name -> query.QueryResult + 169, // 66: tabletmanagerdata.UpdateVReplicationWorkflowRequest.tablet_types:type_name -> topodata.TabletType + 0, // 67: tabletmanagerdata.UpdateVReplicationWorkflowRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 186, // 68: tabletmanagerdata.UpdateVReplicationWorkflowRequest.on_ddl:type_name -> binlogdata.OnDDLAction + 185, // 69: tabletmanagerdata.UpdateVReplicationWorkflowRequest.state:type_name -> binlogdata.VReplicationWorkflowState + 154, // 70: tabletmanagerdata.UpdateVReplicationWorkflowRequest.config_overrides:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest.ConfigOverridesEntry + 171, // 71: tabletmanagerdata.UpdateVReplicationWorkflowResponse.result:type_name -> query.QueryResult + 185, // 72: tabletmanagerdata.UpdateVReplicationWorkflowsRequest.state:type_name -> binlogdata.VReplicationWorkflowState + 171, // 73: tabletmanagerdata.UpdateVReplicationWorkflowsResponse.result:type_name -> query.QueryResult + 156, // 74: tabletmanagerdata.CheckThrottlerResponse.metrics:type_name -> tabletmanagerdata.CheckThrottlerResponse.MetricsEntry + 1, // 75: tabletmanagerdata.CheckThrottlerResponse.response_code:type_name -> tabletmanagerdata.CheckThrottlerResponseCode + 158, // 76: tabletmanagerdata.GetThrottlerStatusResponse.aggregated_metrics:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.AggregatedMetricsEntry + 159, // 77: tabletmanagerdata.GetThrottlerStatusResponse.metric_thresholds:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricThresholdsEntry + 161, // 78: tabletmanagerdata.GetThrottlerStatusResponse.metrics_health:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricsHealthEntry + 162, // 79: tabletmanagerdata.GetThrottlerStatusResponse.throttled_apps:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.ThrottledAppsEntry + 163, // 80: tabletmanagerdata.GetThrottlerStatusResponse.app_checked_metrics:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.AppCheckedMetricsEntry + 165, // 81: tabletmanagerdata.GetThrottlerStatusResponse.recent_apps:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.RecentAppsEntry + 166, // 82: tabletmanagerdata.ChangeTagsRequest.tags:type_name -> tabletmanagerdata.ChangeTagsRequest.TagsEntry + 167, // 83: tabletmanagerdata.ChangeTagsResponse.tags:type_name -> tabletmanagerdata.ChangeTagsResponse.TagsEntry + 182, // 84: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.bls:type_name -> binlogdata.BinlogSource + 181, // 85: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.time_updated:type_name -> vttime.Time + 181, // 86: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.transaction_timestamp:type_name -> vttime.Time + 185, // 87: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.state:type_name -> binlogdata.VReplicationWorkflowState + 181, // 88: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.time_heartbeat:type_name -> vttime.Time + 181, // 89: tabletmanagerdata.ReadVReplicationWorkflowResponse.Stream.time_throttled:type_name -> vttime.Time + 1, // 90: tabletmanagerdata.CheckThrottlerResponse.Metric.response_code:type_name -> tabletmanagerdata.CheckThrottlerResponseCode + 155, // 91: tabletmanagerdata.CheckThrottlerResponse.MetricsEntry.value:type_name -> tabletmanagerdata.CheckThrottlerResponse.Metric + 157, // 92: tabletmanagerdata.GetThrottlerStatusResponse.AggregatedMetricsEntry.value:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricResult + 181, // 93: tabletmanagerdata.GetThrottlerStatusResponse.MetricHealth.last_healthy_at:type_name -> vttime.Time + 160, // 94: tabletmanagerdata.GetThrottlerStatusResponse.MetricsHealthEntry.value:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.MetricHealth + 187, // 95: tabletmanagerdata.GetThrottlerStatusResponse.ThrottledAppsEntry.value:type_name -> topodata.ThrottledAppRule + 181, // 96: tabletmanagerdata.GetThrottlerStatusResponse.RecentApp.checked_at:type_name -> vttime.Time + 1, // 97: tabletmanagerdata.GetThrottlerStatusResponse.RecentApp.response_code:type_name -> tabletmanagerdata.CheckThrottlerResponseCode + 164, // 98: tabletmanagerdata.GetThrottlerStatusResponse.RecentAppsEntry.value:type_name -> tabletmanagerdata.GetThrottlerStatusResponse.RecentApp + 99, // [99:99] is the sub-list for method output_type + 99, // [99:99] is the sub-list for method input_type + 99, // [99:99] is the sub-list for extension type_name + 99, // [99:99] is the sub-list for extension extendee + 0, // [0:99] is the sub-list for field type_name } func init() { file_tabletmanagerdata_proto_init() } @@ -9569,14 +9633,15 @@ func file_tabletmanagerdata_proto_init() { file_tabletmanagerdata_proto_msgTypes[108].OneofWrappers = []any{} file_tabletmanagerdata_proto_msgTypes[130].OneofWrappers = []any{} file_tabletmanagerdata_proto_msgTypes[132].OneofWrappers = []any{} - file_tabletmanagerdata_proto_msgTypes[134].OneofWrappers = []any{} + file_tabletmanagerdata_proto_msgTypes[133].OneofWrappers = []any{} + file_tabletmanagerdata_proto_msgTypes[135].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tabletmanagerdata_proto_rawDesc, NumEnums: 2, - NumMessages: 165, + NumMessages: 166, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go index b833c6b513e..77a2a69b0df 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go @@ -1190,7 +1190,6 @@ func (m *ReplicationStatusResponse) CloneVT() *ReplicationStatusResponse { } r := new(ReplicationStatusResponse) r.Status = m.Status.CloneVT() - r.BackupRunning = m.BackupRunning if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -1968,7 +1967,6 @@ func (m *StopReplicationAndGetStatusResponse) CloneVT() *StopReplicationAndGetSt } r := new(StopReplicationAndGetStatusResponse) r.Status = m.Status.CloneVT() - r.BackupRunning = m.BackupRunning if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -2581,6 +2579,24 @@ func (m *VDiffOptions) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *VDiffTableLastPK) CloneVT() *VDiffTableLastPK { + if m == nil { + return (*VDiffTableLastPK)(nil) + } + r := new(VDiffTableLastPK) + r.Target = m.Target.CloneVT() + r.Source = m.Source.CloneVT() + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *VDiffTableLastPK) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *UpdateVReplicationWorkflowRequest) CloneVT() *UpdateVReplicationWorkflowRequest { if m == nil { return (*UpdateVReplicationWorkflowRequest)(nil) @@ -2609,6 +2625,11 @@ func (m *UpdateVReplicationWorkflowRequest) CloneVT() *UpdateVReplicationWorkflo tmpVal := *rhs r.State = &tmpVal } + if rhs := m.Shards; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.Shards = tmpContainer + } if rhs := m.ConfigOverrides; rhs != nil { tmpContainer := make(map[string]string, len(rhs)) for k, v := range rhs { @@ -2616,6 +2637,10 @@ func (m *UpdateVReplicationWorkflowRequest) CloneVT() *UpdateVReplicationWorkflo } r.ConfigOverrides = tmpContainer } + if rhs := m.Message; rhs != nil { + tmpVal := *rhs + r.Message = &tmpVal + } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -5784,16 +5809,6 @@ func (m *ReplicationStatusResponse) MarshalToSizedBufferVT(dAtA []byte) (int, er i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if m.BackupRunning { - i-- - if m.BackupRunning { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - } if m.Status != nil { size, err := m.Status.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -7601,16 +7616,6 @@ func (m *StopReplicationAndGetStatusResponse) MarshalToSizedBufferVT(dAtA []byte i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if m.BackupRunning { - i-- - if m.BackupRunning { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x18 - } if m.Status != nil { size, err := m.Status.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -9368,6 +9373,59 @@ func (m *VDiffOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *VDiffTableLastPK) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VDiffTableLastPK) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *VDiffTableLastPK) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Source != nil { + size, err := m.Source.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + if m.Target != nil { + size, err := m.Target.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *UpdateVReplicationWorkflowRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -9398,6 +9456,13 @@ func (m *UpdateVReplicationWorkflowRequest) MarshalToSizedBufferVT(dAtA []byte) i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.Message != nil { + i -= len(*m.Message) + copy(dAtA[i:], *m.Message) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(*m.Message))) + i-- + dAtA[i] = 0x4a + } if len(m.ConfigOverrides) > 0 { for k := range m.ConfigOverrides { v := m.ConfigOverrides[k] @@ -9417,6 +9482,15 @@ func (m *UpdateVReplicationWorkflowRequest) MarshalToSizedBufferVT(dAtA []byte) dAtA[i] = 0x42 } } + if len(m.Shards) > 0 { + for iNdEx := len(m.Shards) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Shards[iNdEx]) + copy(dAtA[i:], m.Shards[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Shards[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } if m.State != nil { i = protohelpers.EncodeVarint(dAtA, i, uint64(*m.State)) i-- @@ -11509,9 +11583,6 @@ func (m *ReplicationStatusResponse) SizeVT() (n int) { l = m.Status.SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if m.BackupRunning { - n += 2 - } n += len(m.unknownFields) return n } @@ -12107,9 +12178,6 @@ func (m *StopReplicationAndGetStatusResponse) SizeVT() (n int) { l = m.Status.SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } - if m.BackupRunning { - n += 2 - } n += len(m.unknownFields) return n } @@ -12771,6 +12839,24 @@ func (m *VDiffOptions) SizeVT() (n int) { return n } +func (m *VDiffTableLastPK) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Target != nil { + l = m.Target.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Source != nil { + l = m.Source.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + func (m *UpdateVReplicationWorkflowRequest) SizeVT() (n int) { if m == nil { return 0 @@ -12803,6 +12889,12 @@ func (m *UpdateVReplicationWorkflowRequest) SizeVT() (n int) { if m.State != nil { n += 1 + protohelpers.SizeOfVarint(uint64(*m.State)) } + if len(m.Shards) > 0 { + for _, s := range m.Shards { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } if len(m.ConfigOverrides) > 0 { for k, v := range m.ConfigOverrides { _ = k @@ -12811,6 +12903,10 @@ func (m *UpdateVReplicationWorkflowRequest) SizeVT() (n int) { n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) } } + if m.Message != nil { + l = len(*m.Message) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -19399,26 +19495,6 @@ func (m *ReplicationStatusResponse) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BackupRunning", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.BackupRunning = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -22788,26 +22864,6 @@ func (m *StopReplicationAndGetStatusResponse) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BackupRunning", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.BackupRunning = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -27288,6 +27344,129 @@ func (m *VDiffOptions) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *VDiffTableLastPK) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VDiffTableLastPK: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VDiffTableLastPK: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Target == nil { + m.Target = &query.QueryResult{} + } + if err := m.Target.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Source == nil { + m.Source = &query.QueryResult{} + } + if err := m.Source.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *UpdateVReplicationWorkflowRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -27510,6 +27689,38 @@ func (m *UpdateVReplicationWorkflowRequest) UnmarshalVT(dAtA []byte) error { } } m.State = &v + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Shards", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Shards = append(m.Shards, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConfigOverrides", wireType) @@ -27637,6 +27848,39 @@ func (m *UpdateVReplicationWorkflowRequest) UnmarshalVT(dAtA []byte) error { } m.ConfigOverrides[mapkey] = mapvalue iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Message = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/go/vt/proto/topodata/cached_size.go b/go/vt/proto/topodata/cached_size.go index 94b7fc6818c..3feead01bae 100644 --- a/go/vt/proto/topodata/cached_size.go +++ b/go/vt/proto/topodata/cached_size.go @@ -27,6 +27,10 @@ func (cached *KeyRange) CachedSize(alloc bool) int64 { if alloc { size += int64(96) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } // field Start []byte { size += hack.RuntimeAllocSize(int64(cap(cached.Start))) @@ -45,6 +49,10 @@ func (cached *ThrottledAppRule) CachedSize(alloc bool) int64 { if alloc { size += int64(80) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } // field Name string size += hack.RuntimeAllocSize(int64(len(cached.Name))) // field ExpiresAt *vitess.io/vitess/go/vt/proto/vttime.Time diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index f675a190faa..1ba227db405 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -3222,6 +3222,143 @@ func (x *CompleteSchemaMigrationResponse) GetRowsAffectedByShard() map[string]ui return nil } +type CopySchemaShardRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SourceTabletAlias *topodata.TabletAlias `protobuf:"bytes,1,opt,name=source_tablet_alias,json=sourceTabletAlias,proto3" json:"source_tablet_alias,omitempty"` + Tables []string `protobuf:"bytes,2,rep,name=tables,proto3" json:"tables,omitempty"` + ExcludeTables []string `protobuf:"bytes,3,rep,name=exclude_tables,json=excludeTables,proto3" json:"exclude_tables,omitempty"` + IncludeViews bool `protobuf:"varint,4,opt,name=include_views,json=includeViews,proto3" json:"include_views,omitempty"` + SkipVerify bool `protobuf:"varint,5,opt,name=skip_verify,json=skipVerify,proto3" json:"skip_verify,omitempty"` + WaitReplicasTimeout *vttime.Duration `protobuf:"bytes,6,opt,name=wait_replicas_timeout,json=waitReplicasTimeout,proto3" json:"wait_replicas_timeout,omitempty"` + DestinationKeyspace string `protobuf:"bytes,7,opt,name=destination_keyspace,json=destinationKeyspace,proto3" json:"destination_keyspace,omitempty"` + DestinationShard string `protobuf:"bytes,8,opt,name=destination_shard,json=destinationShard,proto3" json:"destination_shard,omitempty"` +} + +func (x *CopySchemaShardRequest) Reset() { + *x = CopySchemaShardRequest{} + mi := &file_vtctldata_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CopySchemaShardRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CopySchemaShardRequest) ProtoMessage() {} + +func (x *CopySchemaShardRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CopySchemaShardRequest.ProtoReflect.Descriptor instead. +func (*CopySchemaShardRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{38} +} + +func (x *CopySchemaShardRequest) GetSourceTabletAlias() *topodata.TabletAlias { + if x != nil { + return x.SourceTabletAlias + } + return nil +} + +func (x *CopySchemaShardRequest) GetTables() []string { + if x != nil { + return x.Tables + } + return nil +} + +func (x *CopySchemaShardRequest) GetExcludeTables() []string { + if x != nil { + return x.ExcludeTables + } + return nil +} + +func (x *CopySchemaShardRequest) GetIncludeViews() bool { + if x != nil { + return x.IncludeViews + } + return false +} + +func (x *CopySchemaShardRequest) GetSkipVerify() bool { + if x != nil { + return x.SkipVerify + } + return false +} + +func (x *CopySchemaShardRequest) GetWaitReplicasTimeout() *vttime.Duration { + if x != nil { + return x.WaitReplicasTimeout + } + return nil +} + +func (x *CopySchemaShardRequest) GetDestinationKeyspace() string { + if x != nil { + return x.DestinationKeyspace + } + return "" +} + +func (x *CopySchemaShardRequest) GetDestinationShard() string { + if x != nil { + return x.DestinationShard + } + return "" +} + +type CopySchemaShardResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *CopySchemaShardResponse) Reset() { + *x = CopySchemaShardResponse{} + mi := &file_vtctldata_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CopySchemaShardResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CopySchemaShardResponse) ProtoMessage() {} + +func (x *CopySchemaShardResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CopySchemaShardResponse.ProtoReflect.Descriptor instead. +func (*CopySchemaShardResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{39} +} + type CreateKeyspaceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3251,7 +3388,7 @@ type CreateKeyspaceRequest struct { func (x *CreateKeyspaceRequest) Reset() { *x = CreateKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[38] + mi := &file_vtctldata_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3263,7 +3400,7 @@ func (x *CreateKeyspaceRequest) String() string { func (*CreateKeyspaceRequest) ProtoMessage() {} func (x *CreateKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[38] + mi := &file_vtctldata_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3276,7 +3413,7 @@ func (x *CreateKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateKeyspaceRequest.ProtoReflect.Descriptor instead. func (*CreateKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{38} + return file_vtctldata_proto_rawDescGZIP(), []int{40} } func (x *CreateKeyspaceRequest) GetName() string { @@ -3346,7 +3483,7 @@ type CreateKeyspaceResponse struct { func (x *CreateKeyspaceResponse) Reset() { *x = CreateKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[39] + mi := &file_vtctldata_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3358,7 +3495,7 @@ func (x *CreateKeyspaceResponse) String() string { func (*CreateKeyspaceResponse) ProtoMessage() {} func (x *CreateKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[39] + mi := &file_vtctldata_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3371,7 +3508,7 @@ func (x *CreateKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateKeyspaceResponse.ProtoReflect.Descriptor instead. func (*CreateKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{39} + return file_vtctldata_proto_rawDescGZIP(), []int{41} } func (x *CreateKeyspaceResponse) GetKeyspace() *Keyspace { @@ -3400,7 +3537,7 @@ type CreateShardRequest struct { func (x *CreateShardRequest) Reset() { *x = CreateShardRequest{} - mi := &file_vtctldata_proto_msgTypes[40] + mi := &file_vtctldata_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3412,7 +3549,7 @@ func (x *CreateShardRequest) String() string { func (*CreateShardRequest) ProtoMessage() {} func (x *CreateShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[40] + mi := &file_vtctldata_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3425,7 +3562,7 @@ func (x *CreateShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateShardRequest.ProtoReflect.Descriptor instead. func (*CreateShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{40} + return file_vtctldata_proto_rawDescGZIP(), []int{42} } func (x *CreateShardRequest) GetKeyspace() string { @@ -3473,7 +3610,7 @@ type CreateShardResponse struct { func (x *CreateShardResponse) Reset() { *x = CreateShardResponse{} - mi := &file_vtctldata_proto_msgTypes[41] + mi := &file_vtctldata_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3485,7 +3622,7 @@ func (x *CreateShardResponse) String() string { func (*CreateShardResponse) ProtoMessage() {} func (x *CreateShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[41] + mi := &file_vtctldata_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3498,7 +3635,7 @@ func (x *CreateShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateShardResponse.ProtoReflect.Descriptor instead. func (*CreateShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{41} + return file_vtctldata_proto_rawDescGZIP(), []int{43} } func (x *CreateShardResponse) GetKeyspace() *Keyspace { @@ -3533,7 +3670,7 @@ type DeleteCellInfoRequest struct { func (x *DeleteCellInfoRequest) Reset() { *x = DeleteCellInfoRequest{} - mi := &file_vtctldata_proto_msgTypes[42] + mi := &file_vtctldata_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3545,7 +3682,7 @@ func (x *DeleteCellInfoRequest) String() string { func (*DeleteCellInfoRequest) ProtoMessage() {} func (x *DeleteCellInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[42] + mi := &file_vtctldata_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3558,7 +3695,7 @@ func (x *DeleteCellInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteCellInfoRequest.ProtoReflect.Descriptor instead. func (*DeleteCellInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{42} + return file_vtctldata_proto_rawDescGZIP(), []int{44} } func (x *DeleteCellInfoRequest) GetName() string { @@ -3583,7 +3720,7 @@ type DeleteCellInfoResponse struct { func (x *DeleteCellInfoResponse) Reset() { *x = DeleteCellInfoResponse{} - mi := &file_vtctldata_proto_msgTypes[43] + mi := &file_vtctldata_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3595,7 +3732,7 @@ func (x *DeleteCellInfoResponse) String() string { func (*DeleteCellInfoResponse) ProtoMessage() {} func (x *DeleteCellInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[43] + mi := &file_vtctldata_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3608,7 +3745,7 @@ func (x *DeleteCellInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteCellInfoResponse.ProtoReflect.Descriptor instead. func (*DeleteCellInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{43} + return file_vtctldata_proto_rawDescGZIP(), []int{45} } type DeleteCellsAliasRequest struct { @@ -3621,7 +3758,7 @@ type DeleteCellsAliasRequest struct { func (x *DeleteCellsAliasRequest) Reset() { *x = DeleteCellsAliasRequest{} - mi := &file_vtctldata_proto_msgTypes[44] + mi := &file_vtctldata_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3633,7 +3770,7 @@ func (x *DeleteCellsAliasRequest) String() string { func (*DeleteCellsAliasRequest) ProtoMessage() {} func (x *DeleteCellsAliasRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[44] + mi := &file_vtctldata_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3646,7 +3783,7 @@ func (x *DeleteCellsAliasRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteCellsAliasRequest.ProtoReflect.Descriptor instead. func (*DeleteCellsAliasRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{44} + return file_vtctldata_proto_rawDescGZIP(), []int{46} } func (x *DeleteCellsAliasRequest) GetName() string { @@ -3664,7 +3801,7 @@ type DeleteCellsAliasResponse struct { func (x *DeleteCellsAliasResponse) Reset() { *x = DeleteCellsAliasResponse{} - mi := &file_vtctldata_proto_msgTypes[45] + mi := &file_vtctldata_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3676,7 +3813,7 @@ func (x *DeleteCellsAliasResponse) String() string { func (*DeleteCellsAliasResponse) ProtoMessage() {} func (x *DeleteCellsAliasResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[45] + mi := &file_vtctldata_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3689,7 +3826,7 @@ func (x *DeleteCellsAliasResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteCellsAliasResponse.ProtoReflect.Descriptor instead. func (*DeleteCellsAliasResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{45} + return file_vtctldata_proto_rawDescGZIP(), []int{47} } type DeleteKeyspaceRequest struct { @@ -3710,7 +3847,7 @@ type DeleteKeyspaceRequest struct { func (x *DeleteKeyspaceRequest) Reset() { *x = DeleteKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[46] + mi := &file_vtctldata_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3722,7 +3859,7 @@ func (x *DeleteKeyspaceRequest) String() string { func (*DeleteKeyspaceRequest) ProtoMessage() {} func (x *DeleteKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[46] + mi := &file_vtctldata_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3735,7 +3872,7 @@ func (x *DeleteKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteKeyspaceRequest.ProtoReflect.Descriptor instead. func (*DeleteKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{46} + return file_vtctldata_proto_rawDescGZIP(), []int{48} } func (x *DeleteKeyspaceRequest) GetKeyspace() string { @@ -3767,7 +3904,7 @@ type DeleteKeyspaceResponse struct { func (x *DeleteKeyspaceResponse) Reset() { *x = DeleteKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[47] + mi := &file_vtctldata_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3779,7 +3916,7 @@ func (x *DeleteKeyspaceResponse) String() string { func (*DeleteKeyspaceResponse) ProtoMessage() {} func (x *DeleteKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[47] + mi := &file_vtctldata_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3792,7 +3929,7 @@ func (x *DeleteKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteKeyspaceResponse.ProtoReflect.Descriptor instead. func (*DeleteKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{47} + return file_vtctldata_proto_rawDescGZIP(), []int{49} } type DeleteShardsRequest struct { @@ -3817,7 +3954,7 @@ type DeleteShardsRequest struct { func (x *DeleteShardsRequest) Reset() { *x = DeleteShardsRequest{} - mi := &file_vtctldata_proto_msgTypes[48] + mi := &file_vtctldata_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3829,7 +3966,7 @@ func (x *DeleteShardsRequest) String() string { func (*DeleteShardsRequest) ProtoMessage() {} func (x *DeleteShardsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[48] + mi := &file_vtctldata_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3842,7 +3979,7 @@ func (x *DeleteShardsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteShardsRequest.ProtoReflect.Descriptor instead. func (*DeleteShardsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{48} + return file_vtctldata_proto_rawDescGZIP(), []int{50} } func (x *DeleteShardsRequest) GetShards() []*Shard { @@ -3881,7 +4018,7 @@ type DeleteShardsResponse struct { func (x *DeleteShardsResponse) Reset() { *x = DeleteShardsResponse{} - mi := &file_vtctldata_proto_msgTypes[49] + mi := &file_vtctldata_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3893,7 +4030,7 @@ func (x *DeleteShardsResponse) String() string { func (*DeleteShardsResponse) ProtoMessage() {} func (x *DeleteShardsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[49] + mi := &file_vtctldata_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3906,7 +4043,7 @@ func (x *DeleteShardsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteShardsResponse.ProtoReflect.Descriptor instead. func (*DeleteShardsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{49} + return file_vtctldata_proto_rawDescGZIP(), []int{51} } type DeleteSrvVSchemaRequest struct { @@ -3919,7 +4056,7 @@ type DeleteSrvVSchemaRequest struct { func (x *DeleteSrvVSchemaRequest) Reset() { *x = DeleteSrvVSchemaRequest{} - mi := &file_vtctldata_proto_msgTypes[50] + mi := &file_vtctldata_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3931,7 +4068,7 @@ func (x *DeleteSrvVSchemaRequest) String() string { func (*DeleteSrvVSchemaRequest) ProtoMessage() {} func (x *DeleteSrvVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[50] + mi := &file_vtctldata_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3944,7 +4081,7 @@ func (x *DeleteSrvVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteSrvVSchemaRequest.ProtoReflect.Descriptor instead. func (*DeleteSrvVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{50} + return file_vtctldata_proto_rawDescGZIP(), []int{52} } func (x *DeleteSrvVSchemaRequest) GetCell() string { @@ -3962,7 +4099,7 @@ type DeleteSrvVSchemaResponse struct { func (x *DeleteSrvVSchemaResponse) Reset() { *x = DeleteSrvVSchemaResponse{} - mi := &file_vtctldata_proto_msgTypes[51] + mi := &file_vtctldata_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3974,7 +4111,7 @@ func (x *DeleteSrvVSchemaResponse) String() string { func (*DeleteSrvVSchemaResponse) ProtoMessage() {} func (x *DeleteSrvVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[51] + mi := &file_vtctldata_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3987,7 +4124,7 @@ func (x *DeleteSrvVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteSrvVSchemaResponse.ProtoReflect.Descriptor instead. func (*DeleteSrvVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{51} + return file_vtctldata_proto_rawDescGZIP(), []int{53} } type DeleteTabletsRequest struct { @@ -4004,7 +4141,7 @@ type DeleteTabletsRequest struct { func (x *DeleteTabletsRequest) Reset() { *x = DeleteTabletsRequest{} - mi := &file_vtctldata_proto_msgTypes[52] + mi := &file_vtctldata_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4016,7 +4153,7 @@ func (x *DeleteTabletsRequest) String() string { func (*DeleteTabletsRequest) ProtoMessage() {} func (x *DeleteTabletsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[52] + mi := &file_vtctldata_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4029,7 +4166,7 @@ func (x *DeleteTabletsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTabletsRequest.ProtoReflect.Descriptor instead. func (*DeleteTabletsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{52} + return file_vtctldata_proto_rawDescGZIP(), []int{54} } func (x *DeleteTabletsRequest) GetTabletAliases() []*topodata.TabletAlias { @@ -4054,7 +4191,7 @@ type DeleteTabletsResponse struct { func (x *DeleteTabletsResponse) Reset() { *x = DeleteTabletsResponse{} - mi := &file_vtctldata_proto_msgTypes[53] + mi := &file_vtctldata_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4066,7 +4203,7 @@ func (x *DeleteTabletsResponse) String() string { func (*DeleteTabletsResponse) ProtoMessage() {} func (x *DeleteTabletsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[53] + mi := &file_vtctldata_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4079,7 +4216,7 @@ func (x *DeleteTabletsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTabletsResponse.ProtoReflect.Descriptor instead. func (*DeleteTabletsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{53} + return file_vtctldata_proto_rawDescGZIP(), []int{55} } type EmergencyReparentShardRequest struct { @@ -4115,7 +4252,7 @@ type EmergencyReparentShardRequest struct { func (x *EmergencyReparentShardRequest) Reset() { *x = EmergencyReparentShardRequest{} - mi := &file_vtctldata_proto_msgTypes[54] + mi := &file_vtctldata_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4127,7 +4264,7 @@ func (x *EmergencyReparentShardRequest) String() string { func (*EmergencyReparentShardRequest) ProtoMessage() {} func (x *EmergencyReparentShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[54] + mi := &file_vtctldata_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4140,7 +4277,7 @@ func (x *EmergencyReparentShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EmergencyReparentShardRequest.ProtoReflect.Descriptor instead. func (*EmergencyReparentShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{54} + return file_vtctldata_proto_rawDescGZIP(), []int{56} } func (x *EmergencyReparentShardRequest) GetKeyspace() string { @@ -4218,7 +4355,7 @@ type EmergencyReparentShardResponse struct { func (x *EmergencyReparentShardResponse) Reset() { *x = EmergencyReparentShardResponse{} - mi := &file_vtctldata_proto_msgTypes[55] + mi := &file_vtctldata_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4230,7 +4367,7 @@ func (x *EmergencyReparentShardResponse) String() string { func (*EmergencyReparentShardResponse) ProtoMessage() {} func (x *EmergencyReparentShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[55] + mi := &file_vtctldata_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4243,7 +4380,7 @@ func (x *EmergencyReparentShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EmergencyReparentShardResponse.ProtoReflect.Descriptor instead. func (*EmergencyReparentShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{55} + return file_vtctldata_proto_rawDescGZIP(), []int{57} } func (x *EmergencyReparentShardResponse) GetKeyspace() string { @@ -4294,7 +4431,7 @@ type ExecuteFetchAsAppRequest struct { func (x *ExecuteFetchAsAppRequest) Reset() { *x = ExecuteFetchAsAppRequest{} - mi := &file_vtctldata_proto_msgTypes[56] + mi := &file_vtctldata_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4306,7 +4443,7 @@ func (x *ExecuteFetchAsAppRequest) String() string { func (*ExecuteFetchAsAppRequest) ProtoMessage() {} func (x *ExecuteFetchAsAppRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[56] + mi := &file_vtctldata_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4319,7 +4456,7 @@ func (x *ExecuteFetchAsAppRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteFetchAsAppRequest.ProtoReflect.Descriptor instead. func (*ExecuteFetchAsAppRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{56} + return file_vtctldata_proto_rawDescGZIP(), []int{58} } func (x *ExecuteFetchAsAppRequest) GetTabletAlias() *topodata.TabletAlias { @@ -4360,7 +4497,7 @@ type ExecuteFetchAsAppResponse struct { func (x *ExecuteFetchAsAppResponse) Reset() { *x = ExecuteFetchAsAppResponse{} - mi := &file_vtctldata_proto_msgTypes[57] + mi := &file_vtctldata_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4372,7 +4509,7 @@ func (x *ExecuteFetchAsAppResponse) String() string { func (*ExecuteFetchAsAppResponse) ProtoMessage() {} func (x *ExecuteFetchAsAppResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[57] + mi := &file_vtctldata_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4385,7 +4522,7 @@ func (x *ExecuteFetchAsAppResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteFetchAsAppResponse.ProtoReflect.Descriptor instead. func (*ExecuteFetchAsAppResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{57} + return file_vtctldata_proto_rawDescGZIP(), []int{59} } func (x *ExecuteFetchAsAppResponse) GetResult() *query.QueryResult { @@ -4419,7 +4556,7 @@ type ExecuteFetchAsDBARequest struct { func (x *ExecuteFetchAsDBARequest) Reset() { *x = ExecuteFetchAsDBARequest{} - mi := &file_vtctldata_proto_msgTypes[58] + mi := &file_vtctldata_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4431,7 +4568,7 @@ func (x *ExecuteFetchAsDBARequest) String() string { func (*ExecuteFetchAsDBARequest) ProtoMessage() {} func (x *ExecuteFetchAsDBARequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[58] + mi := &file_vtctldata_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4444,7 +4581,7 @@ func (x *ExecuteFetchAsDBARequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteFetchAsDBARequest.ProtoReflect.Descriptor instead. func (*ExecuteFetchAsDBARequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{58} + return file_vtctldata_proto_rawDescGZIP(), []int{60} } func (x *ExecuteFetchAsDBARequest) GetTabletAlias() *topodata.TabletAlias { @@ -4492,7 +4629,7 @@ type ExecuteFetchAsDBAResponse struct { func (x *ExecuteFetchAsDBAResponse) Reset() { *x = ExecuteFetchAsDBAResponse{} - mi := &file_vtctldata_proto_msgTypes[59] + mi := &file_vtctldata_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4504,7 +4641,7 @@ func (x *ExecuteFetchAsDBAResponse) String() string { func (*ExecuteFetchAsDBAResponse) ProtoMessage() {} func (x *ExecuteFetchAsDBAResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[59] + mi := &file_vtctldata_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4517,7 +4654,7 @@ func (x *ExecuteFetchAsDBAResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteFetchAsDBAResponse.ProtoReflect.Descriptor instead. func (*ExecuteFetchAsDBAResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{59} + return file_vtctldata_proto_rawDescGZIP(), []int{61} } func (x *ExecuteFetchAsDBAResponse) GetResult() *query.QueryResult { @@ -4538,7 +4675,7 @@ type ExecuteHookRequest struct { func (x *ExecuteHookRequest) Reset() { *x = ExecuteHookRequest{} - mi := &file_vtctldata_proto_msgTypes[60] + mi := &file_vtctldata_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4550,7 +4687,7 @@ func (x *ExecuteHookRequest) String() string { func (*ExecuteHookRequest) ProtoMessage() {} func (x *ExecuteHookRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[60] + mi := &file_vtctldata_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4563,7 +4700,7 @@ func (x *ExecuteHookRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteHookRequest.ProtoReflect.Descriptor instead. func (*ExecuteHookRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{60} + return file_vtctldata_proto_rawDescGZIP(), []int{62} } func (x *ExecuteHookRequest) GetTabletAlias() *topodata.TabletAlias { @@ -4590,7 +4727,7 @@ type ExecuteHookResponse struct { func (x *ExecuteHookResponse) Reset() { *x = ExecuteHookResponse{} - mi := &file_vtctldata_proto_msgTypes[61] + mi := &file_vtctldata_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4602,7 +4739,7 @@ func (x *ExecuteHookResponse) String() string { func (*ExecuteHookResponse) ProtoMessage() {} func (x *ExecuteHookResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[61] + mi := &file_vtctldata_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4615,7 +4752,7 @@ func (x *ExecuteHookResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteHookResponse.ProtoReflect.Descriptor instead. func (*ExecuteHookResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{61} + return file_vtctldata_proto_rawDescGZIP(), []int{63} } func (x *ExecuteHookResponse) GetHookResult() *tabletmanagerdata.ExecuteHookResponse { @@ -4650,7 +4787,7 @@ type ExecuteMultiFetchAsDBARequest struct { func (x *ExecuteMultiFetchAsDBARequest) Reset() { *x = ExecuteMultiFetchAsDBARequest{} - mi := &file_vtctldata_proto_msgTypes[62] + mi := &file_vtctldata_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4662,7 +4799,7 @@ func (x *ExecuteMultiFetchAsDBARequest) String() string { func (*ExecuteMultiFetchAsDBARequest) ProtoMessage() {} func (x *ExecuteMultiFetchAsDBARequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[62] + mi := &file_vtctldata_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4675,7 +4812,7 @@ func (x *ExecuteMultiFetchAsDBARequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteMultiFetchAsDBARequest.ProtoReflect.Descriptor instead. func (*ExecuteMultiFetchAsDBARequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{62} + return file_vtctldata_proto_rawDescGZIP(), []int{64} } func (x *ExecuteMultiFetchAsDBARequest) GetTabletAlias() *topodata.TabletAlias { @@ -4723,7 +4860,7 @@ type ExecuteMultiFetchAsDBAResponse struct { func (x *ExecuteMultiFetchAsDBAResponse) Reset() { *x = ExecuteMultiFetchAsDBAResponse{} - mi := &file_vtctldata_proto_msgTypes[63] + mi := &file_vtctldata_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4735,7 +4872,7 @@ func (x *ExecuteMultiFetchAsDBAResponse) String() string { func (*ExecuteMultiFetchAsDBAResponse) ProtoMessage() {} func (x *ExecuteMultiFetchAsDBAResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[63] + mi := &file_vtctldata_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4748,7 +4885,7 @@ func (x *ExecuteMultiFetchAsDBAResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecuteMultiFetchAsDBAResponse.ProtoReflect.Descriptor instead. func (*ExecuteMultiFetchAsDBAResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{63} + return file_vtctldata_proto_rawDescGZIP(), []int{65} } func (x *ExecuteMultiFetchAsDBAResponse) GetResults() []*query.QueryResult { @@ -4768,7 +4905,7 @@ type FindAllShardsInKeyspaceRequest struct { func (x *FindAllShardsInKeyspaceRequest) Reset() { *x = FindAllShardsInKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[64] + mi := &file_vtctldata_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4780,7 +4917,7 @@ func (x *FindAllShardsInKeyspaceRequest) String() string { func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} func (x *FindAllShardsInKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[64] + mi := &file_vtctldata_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4793,7 +4930,7 @@ func (x *FindAllShardsInKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindAllShardsInKeyspaceRequest.ProtoReflect.Descriptor instead. func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{64} + return file_vtctldata_proto_rawDescGZIP(), []int{66} } func (x *FindAllShardsInKeyspaceRequest) GetKeyspace() string { @@ -4813,7 +4950,7 @@ type FindAllShardsInKeyspaceResponse struct { func (x *FindAllShardsInKeyspaceResponse) Reset() { *x = FindAllShardsInKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[65] + mi := &file_vtctldata_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4825,7 +4962,7 @@ func (x *FindAllShardsInKeyspaceResponse) String() string { func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} func (x *FindAllShardsInKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[65] + mi := &file_vtctldata_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4838,7 +4975,7 @@ func (x *FindAllShardsInKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindAllShardsInKeyspaceResponse.ProtoReflect.Descriptor instead. func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{65} + return file_vtctldata_proto_rawDescGZIP(), []int{67} } func (x *FindAllShardsInKeyspaceResponse) GetShards() map[string]*Shard { @@ -4859,7 +4996,7 @@ type ForceCutOverSchemaMigrationRequest struct { func (x *ForceCutOverSchemaMigrationRequest) Reset() { *x = ForceCutOverSchemaMigrationRequest{} - mi := &file_vtctldata_proto_msgTypes[66] + mi := &file_vtctldata_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4871,7 +5008,7 @@ func (x *ForceCutOverSchemaMigrationRequest) String() string { func (*ForceCutOverSchemaMigrationRequest) ProtoMessage() {} func (x *ForceCutOverSchemaMigrationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[66] + mi := &file_vtctldata_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4884,7 +5021,7 @@ func (x *ForceCutOverSchemaMigrationRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ForceCutOverSchemaMigrationRequest.ProtoReflect.Descriptor instead. func (*ForceCutOverSchemaMigrationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{66} + return file_vtctldata_proto_rawDescGZIP(), []int{68} } func (x *ForceCutOverSchemaMigrationRequest) GetKeyspace() string { @@ -4911,7 +5048,7 @@ type ForceCutOverSchemaMigrationResponse struct { func (x *ForceCutOverSchemaMigrationResponse) Reset() { *x = ForceCutOverSchemaMigrationResponse{} - mi := &file_vtctldata_proto_msgTypes[67] + mi := &file_vtctldata_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4923,7 +5060,7 @@ func (x *ForceCutOverSchemaMigrationResponse) String() string { func (*ForceCutOverSchemaMigrationResponse) ProtoMessage() {} func (x *ForceCutOverSchemaMigrationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[67] + mi := &file_vtctldata_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4936,7 +5073,7 @@ func (x *ForceCutOverSchemaMigrationResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use ForceCutOverSchemaMigrationResponse.ProtoReflect.Descriptor instead. func (*ForceCutOverSchemaMigrationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{67} + return file_vtctldata_proto_rawDescGZIP(), []int{69} } func (x *ForceCutOverSchemaMigrationResponse) GetRowsAffectedByShard() map[string]uint64 { @@ -4971,7 +5108,7 @@ type GetBackupsRequest struct { func (x *GetBackupsRequest) Reset() { *x = GetBackupsRequest{} - mi := &file_vtctldata_proto_msgTypes[68] + mi := &file_vtctldata_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4983,7 +5120,7 @@ func (x *GetBackupsRequest) String() string { func (*GetBackupsRequest) ProtoMessage() {} func (x *GetBackupsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[68] + mi := &file_vtctldata_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4996,7 +5133,7 @@ func (x *GetBackupsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBackupsRequest.ProtoReflect.Descriptor instead. func (*GetBackupsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{68} + return file_vtctldata_proto_rawDescGZIP(), []int{70} } func (x *GetBackupsRequest) GetKeyspace() string { @@ -5044,7 +5181,7 @@ type GetBackupsResponse struct { func (x *GetBackupsResponse) Reset() { *x = GetBackupsResponse{} - mi := &file_vtctldata_proto_msgTypes[69] + mi := &file_vtctldata_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5056,7 +5193,7 @@ func (x *GetBackupsResponse) String() string { func (*GetBackupsResponse) ProtoMessage() {} func (x *GetBackupsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[69] + mi := &file_vtctldata_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5069,7 +5206,7 @@ func (x *GetBackupsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBackupsResponse.ProtoReflect.Descriptor instead. func (*GetBackupsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{69} + return file_vtctldata_proto_rawDescGZIP(), []int{71} } func (x *GetBackupsResponse) GetBackups() []*mysqlctl.BackupInfo { @@ -5089,7 +5226,7 @@ type GetCellInfoRequest struct { func (x *GetCellInfoRequest) Reset() { *x = GetCellInfoRequest{} - mi := &file_vtctldata_proto_msgTypes[70] + mi := &file_vtctldata_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5101,7 +5238,7 @@ func (x *GetCellInfoRequest) String() string { func (*GetCellInfoRequest) ProtoMessage() {} func (x *GetCellInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[70] + mi := &file_vtctldata_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5114,7 +5251,7 @@ func (x *GetCellInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoRequest.ProtoReflect.Descriptor instead. func (*GetCellInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{70} + return file_vtctldata_proto_rawDescGZIP(), []int{72} } func (x *GetCellInfoRequest) GetCell() string { @@ -5134,7 +5271,7 @@ type GetCellInfoResponse struct { func (x *GetCellInfoResponse) Reset() { *x = GetCellInfoResponse{} - mi := &file_vtctldata_proto_msgTypes[71] + mi := &file_vtctldata_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5146,7 +5283,7 @@ func (x *GetCellInfoResponse) String() string { func (*GetCellInfoResponse) ProtoMessage() {} func (x *GetCellInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[71] + mi := &file_vtctldata_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5159,7 +5296,7 @@ func (x *GetCellInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoResponse.ProtoReflect.Descriptor instead. func (*GetCellInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{71} + return file_vtctldata_proto_rawDescGZIP(), []int{73} } func (x *GetCellInfoResponse) GetCellInfo() *topodata.CellInfo { @@ -5177,7 +5314,7 @@ type GetCellInfoNamesRequest struct { func (x *GetCellInfoNamesRequest) Reset() { *x = GetCellInfoNamesRequest{} - mi := &file_vtctldata_proto_msgTypes[72] + mi := &file_vtctldata_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5189,7 +5326,7 @@ func (x *GetCellInfoNamesRequest) String() string { func (*GetCellInfoNamesRequest) ProtoMessage() {} func (x *GetCellInfoNamesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[72] + mi := &file_vtctldata_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5202,7 +5339,7 @@ func (x *GetCellInfoNamesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoNamesRequest.ProtoReflect.Descriptor instead. func (*GetCellInfoNamesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{72} + return file_vtctldata_proto_rawDescGZIP(), []int{74} } type GetCellInfoNamesResponse struct { @@ -5215,7 +5352,7 @@ type GetCellInfoNamesResponse struct { func (x *GetCellInfoNamesResponse) Reset() { *x = GetCellInfoNamesResponse{} - mi := &file_vtctldata_proto_msgTypes[73] + mi := &file_vtctldata_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5227,7 +5364,7 @@ func (x *GetCellInfoNamesResponse) String() string { func (*GetCellInfoNamesResponse) ProtoMessage() {} func (x *GetCellInfoNamesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[73] + mi := &file_vtctldata_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5240,7 +5377,7 @@ func (x *GetCellInfoNamesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoNamesResponse.ProtoReflect.Descriptor instead. func (*GetCellInfoNamesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{73} + return file_vtctldata_proto_rawDescGZIP(), []int{75} } func (x *GetCellInfoNamesResponse) GetNames() []string { @@ -5258,7 +5395,7 @@ type GetCellsAliasesRequest struct { func (x *GetCellsAliasesRequest) Reset() { *x = GetCellsAliasesRequest{} - mi := &file_vtctldata_proto_msgTypes[74] + mi := &file_vtctldata_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5270,7 +5407,7 @@ func (x *GetCellsAliasesRequest) String() string { func (*GetCellsAliasesRequest) ProtoMessage() {} func (x *GetCellsAliasesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[74] + mi := &file_vtctldata_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5283,7 +5420,7 @@ func (x *GetCellsAliasesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellsAliasesRequest.ProtoReflect.Descriptor instead. func (*GetCellsAliasesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{74} + return file_vtctldata_proto_rawDescGZIP(), []int{76} } type GetCellsAliasesResponse struct { @@ -5296,7 +5433,7 @@ type GetCellsAliasesResponse struct { func (x *GetCellsAliasesResponse) Reset() { *x = GetCellsAliasesResponse{} - mi := &file_vtctldata_proto_msgTypes[75] + mi := &file_vtctldata_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5308,7 +5445,7 @@ func (x *GetCellsAliasesResponse) String() string { func (*GetCellsAliasesResponse) ProtoMessage() {} func (x *GetCellsAliasesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[75] + mi := &file_vtctldata_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5321,7 +5458,7 @@ func (x *GetCellsAliasesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellsAliasesResponse.ProtoReflect.Descriptor instead. func (*GetCellsAliasesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{75} + return file_vtctldata_proto_rawDescGZIP(), []int{77} } func (x *GetCellsAliasesResponse) GetAliases() map[string]*topodata.CellsAlias { @@ -5341,7 +5478,7 @@ type GetFullStatusRequest struct { func (x *GetFullStatusRequest) Reset() { *x = GetFullStatusRequest{} - mi := &file_vtctldata_proto_msgTypes[76] + mi := &file_vtctldata_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5353,7 +5490,7 @@ func (x *GetFullStatusRequest) String() string { func (*GetFullStatusRequest) ProtoMessage() {} func (x *GetFullStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[76] + mi := &file_vtctldata_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5366,7 +5503,7 @@ func (x *GetFullStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFullStatusRequest.ProtoReflect.Descriptor instead. func (*GetFullStatusRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{76} + return file_vtctldata_proto_rawDescGZIP(), []int{78} } func (x *GetFullStatusRequest) GetTabletAlias() *topodata.TabletAlias { @@ -5386,7 +5523,7 @@ type GetFullStatusResponse struct { func (x *GetFullStatusResponse) Reset() { *x = GetFullStatusResponse{} - mi := &file_vtctldata_proto_msgTypes[77] + mi := &file_vtctldata_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5398,7 +5535,7 @@ func (x *GetFullStatusResponse) String() string { func (*GetFullStatusResponse) ProtoMessage() {} func (x *GetFullStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[77] + mi := &file_vtctldata_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5411,7 +5548,7 @@ func (x *GetFullStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFullStatusResponse.ProtoReflect.Descriptor instead. func (*GetFullStatusResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{77} + return file_vtctldata_proto_rawDescGZIP(), []int{79} } func (x *GetFullStatusResponse) GetStatus() *replicationdata.FullStatus { @@ -5429,7 +5566,7 @@ type GetKeyspacesRequest struct { func (x *GetKeyspacesRequest) Reset() { *x = GetKeyspacesRequest{} - mi := &file_vtctldata_proto_msgTypes[78] + mi := &file_vtctldata_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5441,7 +5578,7 @@ func (x *GetKeyspacesRequest) String() string { func (*GetKeyspacesRequest) ProtoMessage() {} func (x *GetKeyspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[78] + mi := &file_vtctldata_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5454,7 +5591,7 @@ func (x *GetKeyspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspacesRequest.ProtoReflect.Descriptor instead. func (*GetKeyspacesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{78} + return file_vtctldata_proto_rawDescGZIP(), []int{80} } type GetKeyspacesResponse struct { @@ -5467,7 +5604,7 @@ type GetKeyspacesResponse struct { func (x *GetKeyspacesResponse) Reset() { *x = GetKeyspacesResponse{} - mi := &file_vtctldata_proto_msgTypes[79] + mi := &file_vtctldata_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5479,7 +5616,7 @@ func (x *GetKeyspacesResponse) String() string { func (*GetKeyspacesResponse) ProtoMessage() {} func (x *GetKeyspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[79] + mi := &file_vtctldata_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5492,7 +5629,7 @@ func (x *GetKeyspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspacesResponse.ProtoReflect.Descriptor instead. func (*GetKeyspacesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{79} + return file_vtctldata_proto_rawDescGZIP(), []int{81} } func (x *GetKeyspacesResponse) GetKeyspaces() []*Keyspace { @@ -5512,7 +5649,7 @@ type GetKeyspaceRequest struct { func (x *GetKeyspaceRequest) Reset() { *x = GetKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[80] + mi := &file_vtctldata_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5524,7 +5661,7 @@ func (x *GetKeyspaceRequest) String() string { func (*GetKeyspaceRequest) ProtoMessage() {} func (x *GetKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[80] + mi := &file_vtctldata_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5537,7 +5674,7 @@ func (x *GetKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspaceRequest.ProtoReflect.Descriptor instead. func (*GetKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{80} + return file_vtctldata_proto_rawDescGZIP(), []int{82} } func (x *GetKeyspaceRequest) GetKeyspace() string { @@ -5557,7 +5694,7 @@ type GetKeyspaceResponse struct { func (x *GetKeyspaceResponse) Reset() { *x = GetKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[81] + mi := &file_vtctldata_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5569,7 +5706,7 @@ func (x *GetKeyspaceResponse) String() string { func (*GetKeyspaceResponse) ProtoMessage() {} func (x *GetKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[81] + mi := &file_vtctldata_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5582,7 +5719,7 @@ func (x *GetKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspaceResponse.ProtoReflect.Descriptor instead. func (*GetKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{81} + return file_vtctldata_proto_rawDescGZIP(), []int{83} } func (x *GetKeyspaceResponse) GetKeyspace() *Keyspace { @@ -5602,7 +5739,7 @@ type GetPermissionsRequest struct { func (x *GetPermissionsRequest) Reset() { *x = GetPermissionsRequest{} - mi := &file_vtctldata_proto_msgTypes[82] + mi := &file_vtctldata_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5614,7 +5751,7 @@ func (x *GetPermissionsRequest) String() string { func (*GetPermissionsRequest) ProtoMessage() {} func (x *GetPermissionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[82] + mi := &file_vtctldata_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5627,7 +5764,7 @@ func (x *GetPermissionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPermissionsRequest.ProtoReflect.Descriptor instead. func (*GetPermissionsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{82} + return file_vtctldata_proto_rawDescGZIP(), []int{84} } func (x *GetPermissionsRequest) GetTabletAlias() *topodata.TabletAlias { @@ -5647,7 +5784,7 @@ type GetPermissionsResponse struct { func (x *GetPermissionsResponse) Reset() { *x = GetPermissionsResponse{} - mi := &file_vtctldata_proto_msgTypes[83] + mi := &file_vtctldata_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5659,7 +5796,7 @@ func (x *GetPermissionsResponse) String() string { func (*GetPermissionsResponse) ProtoMessage() {} func (x *GetPermissionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[83] + mi := &file_vtctldata_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5672,7 +5809,7 @@ func (x *GetPermissionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPermissionsResponse.ProtoReflect.Descriptor instead. func (*GetPermissionsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{83} + return file_vtctldata_proto_rawDescGZIP(), []int{85} } func (x *GetPermissionsResponse) GetPermissions() *tabletmanagerdata.Permissions { @@ -5690,7 +5827,7 @@ type GetKeyspaceRoutingRulesRequest struct { func (x *GetKeyspaceRoutingRulesRequest) Reset() { *x = GetKeyspaceRoutingRulesRequest{} - mi := &file_vtctldata_proto_msgTypes[84] + mi := &file_vtctldata_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5702,7 +5839,7 @@ func (x *GetKeyspaceRoutingRulesRequest) String() string { func (*GetKeyspaceRoutingRulesRequest) ProtoMessage() {} func (x *GetKeyspaceRoutingRulesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[84] + mi := &file_vtctldata_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5715,7 +5852,7 @@ func (x *GetKeyspaceRoutingRulesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspaceRoutingRulesRequest.ProtoReflect.Descriptor instead. func (*GetKeyspaceRoutingRulesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{84} + return file_vtctldata_proto_rawDescGZIP(), []int{86} } type GetKeyspaceRoutingRulesResponse struct { @@ -5728,7 +5865,7 @@ type GetKeyspaceRoutingRulesResponse struct { func (x *GetKeyspaceRoutingRulesResponse) Reset() { *x = GetKeyspaceRoutingRulesResponse{} - mi := &file_vtctldata_proto_msgTypes[85] + mi := &file_vtctldata_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5740,7 +5877,7 @@ func (x *GetKeyspaceRoutingRulesResponse) String() string { func (*GetKeyspaceRoutingRulesResponse) ProtoMessage() {} func (x *GetKeyspaceRoutingRulesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[85] + mi := &file_vtctldata_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5753,7 +5890,7 @@ func (x *GetKeyspaceRoutingRulesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspaceRoutingRulesResponse.ProtoReflect.Descriptor instead. func (*GetKeyspaceRoutingRulesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{85} + return file_vtctldata_proto_rawDescGZIP(), []int{87} } func (x *GetKeyspaceRoutingRulesResponse) GetKeyspaceRoutingRules() *vschema.KeyspaceRoutingRules { @@ -5771,7 +5908,7 @@ type GetRoutingRulesRequest struct { func (x *GetRoutingRulesRequest) Reset() { *x = GetRoutingRulesRequest{} - mi := &file_vtctldata_proto_msgTypes[86] + mi := &file_vtctldata_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5783,7 +5920,7 @@ func (x *GetRoutingRulesRequest) String() string { func (*GetRoutingRulesRequest) ProtoMessage() {} func (x *GetRoutingRulesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[86] + mi := &file_vtctldata_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5796,7 +5933,7 @@ func (x *GetRoutingRulesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoutingRulesRequest.ProtoReflect.Descriptor instead. func (*GetRoutingRulesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{86} + return file_vtctldata_proto_rawDescGZIP(), []int{88} } type GetRoutingRulesResponse struct { @@ -5809,7 +5946,7 @@ type GetRoutingRulesResponse struct { func (x *GetRoutingRulesResponse) Reset() { *x = GetRoutingRulesResponse{} - mi := &file_vtctldata_proto_msgTypes[87] + mi := &file_vtctldata_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5821,7 +5958,7 @@ func (x *GetRoutingRulesResponse) String() string { func (*GetRoutingRulesResponse) ProtoMessage() {} func (x *GetRoutingRulesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[87] + mi := &file_vtctldata_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5834,7 +5971,7 @@ func (x *GetRoutingRulesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoutingRulesResponse.ProtoReflect.Descriptor instead. func (*GetRoutingRulesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{87} + return file_vtctldata_proto_rawDescGZIP(), []int{89} } func (x *GetRoutingRulesResponse) GetRoutingRules() *vschema.RoutingRules { @@ -5872,7 +6009,7 @@ type GetSchemaRequest struct { func (x *GetSchemaRequest) Reset() { *x = GetSchemaRequest{} - mi := &file_vtctldata_proto_msgTypes[88] + mi := &file_vtctldata_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5884,7 +6021,7 @@ func (x *GetSchemaRequest) String() string { func (*GetSchemaRequest) ProtoMessage() {} func (x *GetSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[88] + mi := &file_vtctldata_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5897,7 +6034,7 @@ func (x *GetSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaRequest.ProtoReflect.Descriptor instead. func (*GetSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{88} + return file_vtctldata_proto_rawDescGZIP(), []int{90} } func (x *GetSchemaRequest) GetTabletAlias() *topodata.TabletAlias { @@ -5959,7 +6096,7 @@ type GetSchemaResponse struct { func (x *GetSchemaResponse) Reset() { *x = GetSchemaResponse{} - mi := &file_vtctldata_proto_msgTypes[89] + mi := &file_vtctldata_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5971,7 +6108,7 @@ func (x *GetSchemaResponse) String() string { func (*GetSchemaResponse) ProtoMessage() {} func (x *GetSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[89] + mi := &file_vtctldata_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5984,7 +6121,7 @@ func (x *GetSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaResponse.ProtoReflect.Descriptor instead. func (*GetSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{89} + return file_vtctldata_proto_rawDescGZIP(), []int{91} } func (x *GetSchemaResponse) GetSchema() *tabletmanagerdata.SchemaDefinition { @@ -6029,7 +6166,7 @@ type GetSchemaMigrationsRequest struct { func (x *GetSchemaMigrationsRequest) Reset() { *x = GetSchemaMigrationsRequest{} - mi := &file_vtctldata_proto_msgTypes[90] + mi := &file_vtctldata_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6041,7 +6178,7 @@ func (x *GetSchemaMigrationsRequest) String() string { func (*GetSchemaMigrationsRequest) ProtoMessage() {} func (x *GetSchemaMigrationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[90] + mi := &file_vtctldata_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6054,7 +6191,7 @@ func (x *GetSchemaMigrationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaMigrationsRequest.ProtoReflect.Descriptor instead. func (*GetSchemaMigrationsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{90} + return file_vtctldata_proto_rawDescGZIP(), []int{92} } func (x *GetSchemaMigrationsRequest) GetKeyspace() string { @@ -6123,7 +6260,7 @@ type GetSchemaMigrationsResponse struct { func (x *GetSchemaMigrationsResponse) Reset() { *x = GetSchemaMigrationsResponse{} - mi := &file_vtctldata_proto_msgTypes[91] + mi := &file_vtctldata_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6135,7 +6272,7 @@ func (x *GetSchemaMigrationsResponse) String() string { func (*GetSchemaMigrationsResponse) ProtoMessage() {} func (x *GetSchemaMigrationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[91] + mi := &file_vtctldata_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6148,7 +6285,7 @@ func (x *GetSchemaMigrationsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaMigrationsResponse.ProtoReflect.Descriptor instead. func (*GetSchemaMigrationsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{91} + return file_vtctldata_proto_rawDescGZIP(), []int{93} } func (x *GetSchemaMigrationsResponse) GetMigrations() []*SchemaMigration { @@ -6172,7 +6309,7 @@ type GetShardReplicationRequest struct { func (x *GetShardReplicationRequest) Reset() { *x = GetShardReplicationRequest{} - mi := &file_vtctldata_proto_msgTypes[92] + mi := &file_vtctldata_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6184,7 +6321,7 @@ func (x *GetShardReplicationRequest) String() string { func (*GetShardReplicationRequest) ProtoMessage() {} func (x *GetShardReplicationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[92] + mi := &file_vtctldata_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6197,7 +6334,7 @@ func (x *GetShardReplicationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardReplicationRequest.ProtoReflect.Descriptor instead. func (*GetShardReplicationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{92} + return file_vtctldata_proto_rawDescGZIP(), []int{94} } func (x *GetShardReplicationRequest) GetKeyspace() string { @@ -6231,7 +6368,7 @@ type GetShardReplicationResponse struct { func (x *GetShardReplicationResponse) Reset() { *x = GetShardReplicationResponse{} - mi := &file_vtctldata_proto_msgTypes[93] + mi := &file_vtctldata_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6243,7 +6380,7 @@ func (x *GetShardReplicationResponse) String() string { func (*GetShardReplicationResponse) ProtoMessage() {} func (x *GetShardReplicationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[93] + mi := &file_vtctldata_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6256,7 +6393,7 @@ func (x *GetShardReplicationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardReplicationResponse.ProtoReflect.Descriptor instead. func (*GetShardReplicationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{93} + return file_vtctldata_proto_rawDescGZIP(), []int{95} } func (x *GetShardReplicationResponse) GetShardReplicationByCell() map[string]*topodata.ShardReplication { @@ -6277,7 +6414,7 @@ type GetShardRequest struct { func (x *GetShardRequest) Reset() { *x = GetShardRequest{} - mi := &file_vtctldata_proto_msgTypes[94] + mi := &file_vtctldata_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6289,7 +6426,7 @@ func (x *GetShardRequest) String() string { func (*GetShardRequest) ProtoMessage() {} func (x *GetShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[94] + mi := &file_vtctldata_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6302,7 +6439,7 @@ func (x *GetShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardRequest.ProtoReflect.Descriptor instead. func (*GetShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{94} + return file_vtctldata_proto_rawDescGZIP(), []int{96} } func (x *GetShardRequest) GetKeyspace() string { @@ -6329,7 +6466,7 @@ type GetShardResponse struct { func (x *GetShardResponse) Reset() { *x = GetShardResponse{} - mi := &file_vtctldata_proto_msgTypes[95] + mi := &file_vtctldata_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6341,7 +6478,7 @@ func (x *GetShardResponse) String() string { func (*GetShardResponse) ProtoMessage() {} func (x *GetShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[95] + mi := &file_vtctldata_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6354,7 +6491,7 @@ func (x *GetShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardResponse.ProtoReflect.Descriptor instead. func (*GetShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{95} + return file_vtctldata_proto_rawDescGZIP(), []int{97} } func (x *GetShardResponse) GetShard() *Shard { @@ -6372,7 +6509,7 @@ type GetShardRoutingRulesRequest struct { func (x *GetShardRoutingRulesRequest) Reset() { *x = GetShardRoutingRulesRequest{} - mi := &file_vtctldata_proto_msgTypes[96] + mi := &file_vtctldata_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6384,7 +6521,7 @@ func (x *GetShardRoutingRulesRequest) String() string { func (*GetShardRoutingRulesRequest) ProtoMessage() {} func (x *GetShardRoutingRulesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[96] + mi := &file_vtctldata_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6397,7 +6534,7 @@ func (x *GetShardRoutingRulesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardRoutingRulesRequest.ProtoReflect.Descriptor instead. func (*GetShardRoutingRulesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{96} + return file_vtctldata_proto_rawDescGZIP(), []int{98} } type GetShardRoutingRulesResponse struct { @@ -6410,7 +6547,7 @@ type GetShardRoutingRulesResponse struct { func (x *GetShardRoutingRulesResponse) Reset() { *x = GetShardRoutingRulesResponse{} - mi := &file_vtctldata_proto_msgTypes[97] + mi := &file_vtctldata_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6422,7 +6559,7 @@ func (x *GetShardRoutingRulesResponse) String() string { func (*GetShardRoutingRulesResponse) ProtoMessage() {} func (x *GetShardRoutingRulesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[97] + mi := &file_vtctldata_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6435,7 +6572,7 @@ func (x *GetShardRoutingRulesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardRoutingRulesResponse.ProtoReflect.Descriptor instead. func (*GetShardRoutingRulesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{97} + return file_vtctldata_proto_rawDescGZIP(), []int{99} } func (x *GetShardRoutingRulesResponse) GetShardRoutingRules() *vschema.ShardRoutingRules { @@ -6455,7 +6592,7 @@ type GetSrvKeyspaceNamesRequest struct { func (x *GetSrvKeyspaceNamesRequest) Reset() { *x = GetSrvKeyspaceNamesRequest{} - mi := &file_vtctldata_proto_msgTypes[98] + mi := &file_vtctldata_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6467,7 +6604,7 @@ func (x *GetSrvKeyspaceNamesRequest) String() string { func (*GetSrvKeyspaceNamesRequest) ProtoMessage() {} func (x *GetSrvKeyspaceNamesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[98] + mi := &file_vtctldata_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6480,7 +6617,7 @@ func (x *GetSrvKeyspaceNamesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspaceNamesRequest.ProtoReflect.Descriptor instead. func (*GetSrvKeyspaceNamesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{98} + return file_vtctldata_proto_rawDescGZIP(), []int{100} } func (x *GetSrvKeyspaceNamesRequest) GetCells() []string { @@ -6501,7 +6638,7 @@ type GetSrvKeyspaceNamesResponse struct { func (x *GetSrvKeyspaceNamesResponse) Reset() { *x = GetSrvKeyspaceNamesResponse{} - mi := &file_vtctldata_proto_msgTypes[99] + mi := &file_vtctldata_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6513,7 +6650,7 @@ func (x *GetSrvKeyspaceNamesResponse) String() string { func (*GetSrvKeyspaceNamesResponse) ProtoMessage() {} func (x *GetSrvKeyspaceNamesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[99] + mi := &file_vtctldata_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6526,7 +6663,7 @@ func (x *GetSrvKeyspaceNamesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspaceNamesResponse.ProtoReflect.Descriptor instead. func (*GetSrvKeyspaceNamesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{99} + return file_vtctldata_proto_rawDescGZIP(), []int{101} } func (x *GetSrvKeyspaceNamesResponse) GetNames() map[string]*GetSrvKeyspaceNamesResponse_NameList { @@ -6549,7 +6686,7 @@ type GetSrvKeyspacesRequest struct { func (x *GetSrvKeyspacesRequest) Reset() { *x = GetSrvKeyspacesRequest{} - mi := &file_vtctldata_proto_msgTypes[100] + mi := &file_vtctldata_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6561,7 +6698,7 @@ func (x *GetSrvKeyspacesRequest) String() string { func (*GetSrvKeyspacesRequest) ProtoMessage() {} func (x *GetSrvKeyspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[100] + mi := &file_vtctldata_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6574,7 +6711,7 @@ func (x *GetSrvKeyspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspacesRequest.ProtoReflect.Descriptor instead. func (*GetSrvKeyspacesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{100} + return file_vtctldata_proto_rawDescGZIP(), []int{102} } func (x *GetSrvKeyspacesRequest) GetKeyspace() string { @@ -6602,7 +6739,7 @@ type GetSrvKeyspacesResponse struct { func (x *GetSrvKeyspacesResponse) Reset() { *x = GetSrvKeyspacesResponse{} - mi := &file_vtctldata_proto_msgTypes[101] + mi := &file_vtctldata_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6614,7 +6751,7 @@ func (x *GetSrvKeyspacesResponse) String() string { func (*GetSrvKeyspacesResponse) ProtoMessage() {} func (x *GetSrvKeyspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[101] + mi := &file_vtctldata_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6627,7 +6764,7 @@ func (x *GetSrvKeyspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspacesResponse.ProtoReflect.Descriptor instead. func (*GetSrvKeyspacesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{101} + return file_vtctldata_proto_rawDescGZIP(), []int{103} } func (x *GetSrvKeyspacesResponse) GetSrvKeyspaces() map[string]*topodata.SrvKeyspace { @@ -6670,7 +6807,7 @@ type UpdateThrottlerConfigRequest struct { func (x *UpdateThrottlerConfigRequest) Reset() { *x = UpdateThrottlerConfigRequest{} - mi := &file_vtctldata_proto_msgTypes[102] + mi := &file_vtctldata_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6682,7 +6819,7 @@ func (x *UpdateThrottlerConfigRequest) String() string { func (*UpdateThrottlerConfigRequest) ProtoMessage() {} func (x *UpdateThrottlerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[102] + mi := &file_vtctldata_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6695,7 +6832,7 @@ func (x *UpdateThrottlerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateThrottlerConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateThrottlerConfigRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{102} + return file_vtctldata_proto_rawDescGZIP(), []int{104} } func (x *UpdateThrottlerConfigRequest) GetKeyspace() string { @@ -6790,7 +6927,7 @@ type UpdateThrottlerConfigResponse struct { func (x *UpdateThrottlerConfigResponse) Reset() { *x = UpdateThrottlerConfigResponse{} - mi := &file_vtctldata_proto_msgTypes[103] + mi := &file_vtctldata_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6802,7 +6939,7 @@ func (x *UpdateThrottlerConfigResponse) String() string { func (*UpdateThrottlerConfigResponse) ProtoMessage() {} func (x *UpdateThrottlerConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[103] + mi := &file_vtctldata_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6815,7 +6952,7 @@ func (x *UpdateThrottlerConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateThrottlerConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateThrottlerConfigResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{103} + return file_vtctldata_proto_rawDescGZIP(), []int{105} } type GetSrvVSchemaRequest struct { @@ -6828,7 +6965,7 @@ type GetSrvVSchemaRequest struct { func (x *GetSrvVSchemaRequest) Reset() { *x = GetSrvVSchemaRequest{} - mi := &file_vtctldata_proto_msgTypes[104] + mi := &file_vtctldata_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6840,7 +6977,7 @@ func (x *GetSrvVSchemaRequest) String() string { func (*GetSrvVSchemaRequest) ProtoMessage() {} func (x *GetSrvVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[104] + mi := &file_vtctldata_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6853,7 +6990,7 @@ func (x *GetSrvVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemaRequest.ProtoReflect.Descriptor instead. func (*GetSrvVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{104} + return file_vtctldata_proto_rawDescGZIP(), []int{106} } func (x *GetSrvVSchemaRequest) GetCell() string { @@ -6873,7 +7010,7 @@ type GetSrvVSchemaResponse struct { func (x *GetSrvVSchemaResponse) Reset() { *x = GetSrvVSchemaResponse{} - mi := &file_vtctldata_proto_msgTypes[105] + mi := &file_vtctldata_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6885,7 +7022,7 @@ func (x *GetSrvVSchemaResponse) String() string { func (*GetSrvVSchemaResponse) ProtoMessage() {} func (x *GetSrvVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[105] + mi := &file_vtctldata_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6898,7 +7035,7 @@ func (x *GetSrvVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemaResponse.ProtoReflect.Descriptor instead. func (*GetSrvVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{105} + return file_vtctldata_proto_rawDescGZIP(), []int{107} } func (x *GetSrvVSchemaResponse) GetSrvVSchema() *vschema.SrvVSchema { @@ -6918,7 +7055,7 @@ type GetSrvVSchemasRequest struct { func (x *GetSrvVSchemasRequest) Reset() { *x = GetSrvVSchemasRequest{} - mi := &file_vtctldata_proto_msgTypes[106] + mi := &file_vtctldata_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6930,7 +7067,7 @@ func (x *GetSrvVSchemasRequest) String() string { func (*GetSrvVSchemasRequest) ProtoMessage() {} func (x *GetSrvVSchemasRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[106] + mi := &file_vtctldata_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6943,7 +7080,7 @@ func (x *GetSrvVSchemasRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemasRequest.ProtoReflect.Descriptor instead. func (*GetSrvVSchemasRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{106} + return file_vtctldata_proto_rawDescGZIP(), []int{108} } func (x *GetSrvVSchemasRequest) GetCells() []string { @@ -6964,7 +7101,7 @@ type GetSrvVSchemasResponse struct { func (x *GetSrvVSchemasResponse) Reset() { *x = GetSrvVSchemasResponse{} - mi := &file_vtctldata_proto_msgTypes[107] + mi := &file_vtctldata_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6976,7 +7113,7 @@ func (x *GetSrvVSchemasResponse) String() string { func (*GetSrvVSchemasResponse) ProtoMessage() {} func (x *GetSrvVSchemasResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[107] + mi := &file_vtctldata_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6989,7 +7126,7 @@ func (x *GetSrvVSchemasResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemasResponse.ProtoReflect.Descriptor instead. func (*GetSrvVSchemasResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{107} + return file_vtctldata_proto_rawDescGZIP(), []int{109} } func (x *GetSrvVSchemasResponse) GetSrvVSchemas() map[string]*vschema.SrvVSchema { @@ -7009,7 +7146,7 @@ type GetTabletRequest struct { func (x *GetTabletRequest) Reset() { *x = GetTabletRequest{} - mi := &file_vtctldata_proto_msgTypes[108] + mi := &file_vtctldata_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7021,7 +7158,7 @@ func (x *GetTabletRequest) String() string { func (*GetTabletRequest) ProtoMessage() {} func (x *GetTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[108] + mi := &file_vtctldata_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7034,7 +7171,7 @@ func (x *GetTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletRequest.ProtoReflect.Descriptor instead. func (*GetTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{108} + return file_vtctldata_proto_rawDescGZIP(), []int{110} } func (x *GetTabletRequest) GetTabletAlias() *topodata.TabletAlias { @@ -7054,7 +7191,7 @@ type GetTabletResponse struct { func (x *GetTabletResponse) Reset() { *x = GetTabletResponse{} - mi := &file_vtctldata_proto_msgTypes[109] + mi := &file_vtctldata_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7066,7 +7203,7 @@ func (x *GetTabletResponse) String() string { func (*GetTabletResponse) ProtoMessage() {} func (x *GetTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[109] + mi := &file_vtctldata_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7079,7 +7216,7 @@ func (x *GetTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletResponse.ProtoReflect.Descriptor instead. func (*GetTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{109} + return file_vtctldata_proto_rawDescGZIP(), []int{111} } func (x *GetTabletResponse) GetTablet() *topodata.Tablet { @@ -7120,7 +7257,7 @@ type GetTabletsRequest struct { func (x *GetTabletsRequest) Reset() { *x = GetTabletsRequest{} - mi := &file_vtctldata_proto_msgTypes[110] + mi := &file_vtctldata_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7132,7 +7269,7 @@ func (x *GetTabletsRequest) String() string { func (*GetTabletsRequest) ProtoMessage() {} func (x *GetTabletsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[110] + mi := &file_vtctldata_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7145,7 +7282,7 @@ func (x *GetTabletsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletsRequest.ProtoReflect.Descriptor instead. func (*GetTabletsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{110} + return file_vtctldata_proto_rawDescGZIP(), []int{112} } func (x *GetTabletsRequest) GetKeyspace() string { @@ -7200,7 +7337,7 @@ type GetTabletsResponse struct { func (x *GetTabletsResponse) Reset() { *x = GetTabletsResponse{} - mi := &file_vtctldata_proto_msgTypes[111] + mi := &file_vtctldata_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7212,7 +7349,7 @@ func (x *GetTabletsResponse) String() string { func (*GetTabletsResponse) ProtoMessage() {} func (x *GetTabletsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[111] + mi := &file_vtctldata_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7225,7 +7362,7 @@ func (x *GetTabletsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletsResponse.ProtoReflect.Descriptor instead. func (*GetTabletsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{111} + return file_vtctldata_proto_rawDescGZIP(), []int{113} } func (x *GetTabletsResponse) GetTablets() []*topodata.Tablet { @@ -7246,7 +7383,7 @@ type GetThrottlerStatusRequest struct { func (x *GetThrottlerStatusRequest) Reset() { *x = GetThrottlerStatusRequest{} - mi := &file_vtctldata_proto_msgTypes[112] + mi := &file_vtctldata_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7258,7 +7395,7 @@ func (x *GetThrottlerStatusRequest) String() string { func (*GetThrottlerStatusRequest) ProtoMessage() {} func (x *GetThrottlerStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[112] + mi := &file_vtctldata_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7271,7 +7408,7 @@ func (x *GetThrottlerStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetThrottlerStatusRequest.ProtoReflect.Descriptor instead. func (*GetThrottlerStatusRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{112} + return file_vtctldata_proto_rawDescGZIP(), []int{114} } func (x *GetThrottlerStatusRequest) GetTabletAlias() *topodata.TabletAlias { @@ -7291,7 +7428,7 @@ type GetThrottlerStatusResponse struct { func (x *GetThrottlerStatusResponse) Reset() { *x = GetThrottlerStatusResponse{} - mi := &file_vtctldata_proto_msgTypes[113] + mi := &file_vtctldata_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7303,7 +7440,7 @@ func (x *GetThrottlerStatusResponse) String() string { func (*GetThrottlerStatusResponse) ProtoMessage() {} func (x *GetThrottlerStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[113] + mi := &file_vtctldata_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7316,7 +7453,7 @@ func (x *GetThrottlerStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetThrottlerStatusResponse.ProtoReflect.Descriptor instead. func (*GetThrottlerStatusResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{113} + return file_vtctldata_proto_rawDescGZIP(), []int{115} } func (x *GetThrottlerStatusResponse) GetStatus() *tabletmanagerdata.GetThrottlerStatusResponse { @@ -7338,7 +7475,7 @@ type GetTopologyPathRequest struct { func (x *GetTopologyPathRequest) Reset() { *x = GetTopologyPathRequest{} - mi := &file_vtctldata_proto_msgTypes[114] + mi := &file_vtctldata_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7350,7 +7487,7 @@ func (x *GetTopologyPathRequest) String() string { func (*GetTopologyPathRequest) ProtoMessage() {} func (x *GetTopologyPathRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[114] + mi := &file_vtctldata_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7363,7 +7500,7 @@ func (x *GetTopologyPathRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTopologyPathRequest.ProtoReflect.Descriptor instead. func (*GetTopologyPathRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{114} + return file_vtctldata_proto_rawDescGZIP(), []int{116} } func (x *GetTopologyPathRequest) GetPath() string { @@ -7397,7 +7534,7 @@ type GetTopologyPathResponse struct { func (x *GetTopologyPathResponse) Reset() { *x = GetTopologyPathResponse{} - mi := &file_vtctldata_proto_msgTypes[115] + mi := &file_vtctldata_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7409,7 +7546,7 @@ func (x *GetTopologyPathResponse) String() string { func (*GetTopologyPathResponse) ProtoMessage() {} func (x *GetTopologyPathResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[115] + mi := &file_vtctldata_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7422,7 +7559,7 @@ func (x *GetTopologyPathResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTopologyPathResponse.ProtoReflect.Descriptor instead. func (*GetTopologyPathResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{115} + return file_vtctldata_proto_rawDescGZIP(), []int{117} } func (x *GetTopologyPathResponse) GetCell() *TopologyCell { @@ -7448,7 +7585,7 @@ type TopologyCell struct { func (x *TopologyCell) Reset() { *x = TopologyCell{} - mi := &file_vtctldata_proto_msgTypes[116] + mi := &file_vtctldata_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7460,7 +7597,7 @@ func (x *TopologyCell) String() string { func (*TopologyCell) ProtoMessage() {} func (x *TopologyCell) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[116] + mi := &file_vtctldata_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7473,7 +7610,7 @@ func (x *TopologyCell) ProtoReflect() protoreflect.Message { // Deprecated: Use TopologyCell.ProtoReflect.Descriptor instead. func (*TopologyCell) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{116} + return file_vtctldata_proto_rawDescGZIP(), []int{118} } func (x *TopologyCell) GetName() string { @@ -7522,7 +7659,7 @@ type GetUnresolvedTransactionsRequest struct { func (x *GetUnresolvedTransactionsRequest) Reset() { *x = GetUnresolvedTransactionsRequest{} - mi := &file_vtctldata_proto_msgTypes[117] + mi := &file_vtctldata_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7534,7 +7671,7 @@ func (x *GetUnresolvedTransactionsRequest) String() string { func (*GetUnresolvedTransactionsRequest) ProtoMessage() {} func (x *GetUnresolvedTransactionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[117] + mi := &file_vtctldata_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7547,7 +7684,7 @@ func (x *GetUnresolvedTransactionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUnresolvedTransactionsRequest.ProtoReflect.Descriptor instead. func (*GetUnresolvedTransactionsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{117} + return file_vtctldata_proto_rawDescGZIP(), []int{119} } func (x *GetUnresolvedTransactionsRequest) GetKeyspace() string { @@ -7574,7 +7711,7 @@ type GetUnresolvedTransactionsResponse struct { func (x *GetUnresolvedTransactionsResponse) Reset() { *x = GetUnresolvedTransactionsResponse{} - mi := &file_vtctldata_proto_msgTypes[118] + mi := &file_vtctldata_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7586,7 +7723,7 @@ func (x *GetUnresolvedTransactionsResponse) String() string { func (*GetUnresolvedTransactionsResponse) ProtoMessage() {} func (x *GetUnresolvedTransactionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[118] + mi := &file_vtctldata_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7599,7 +7736,7 @@ func (x *GetUnresolvedTransactionsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use GetUnresolvedTransactionsResponse.ProtoReflect.Descriptor instead. func (*GetUnresolvedTransactionsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{118} + return file_vtctldata_proto_rawDescGZIP(), []int{120} } func (x *GetUnresolvedTransactionsResponse) GetTransactions() []*query.TransactionMetadata { @@ -7619,7 +7756,7 @@ type GetTransactionInfoRequest struct { func (x *GetTransactionInfoRequest) Reset() { *x = GetTransactionInfoRequest{} - mi := &file_vtctldata_proto_msgTypes[119] + mi := &file_vtctldata_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7631,7 +7768,7 @@ func (x *GetTransactionInfoRequest) String() string { func (*GetTransactionInfoRequest) ProtoMessage() {} func (x *GetTransactionInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[119] + mi := &file_vtctldata_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7644,7 +7781,7 @@ func (x *GetTransactionInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTransactionInfoRequest.ProtoReflect.Descriptor instead. func (*GetTransactionInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{119} + return file_vtctldata_proto_rawDescGZIP(), []int{121} } func (x *GetTransactionInfoRequest) GetDtid() string { @@ -7668,7 +7805,7 @@ type ShardTransactionState struct { func (x *ShardTransactionState) Reset() { *x = ShardTransactionState{} - mi := &file_vtctldata_proto_msgTypes[120] + mi := &file_vtctldata_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7680,7 +7817,7 @@ func (x *ShardTransactionState) String() string { func (*ShardTransactionState) ProtoMessage() {} func (x *ShardTransactionState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[120] + mi := &file_vtctldata_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7693,7 +7830,7 @@ func (x *ShardTransactionState) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardTransactionState.ProtoReflect.Descriptor instead. func (*ShardTransactionState) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{120} + return file_vtctldata_proto_rawDescGZIP(), []int{122} } func (x *ShardTransactionState) GetShard() string { @@ -7742,7 +7879,7 @@ type GetTransactionInfoResponse struct { func (x *GetTransactionInfoResponse) Reset() { *x = GetTransactionInfoResponse{} - mi := &file_vtctldata_proto_msgTypes[121] + mi := &file_vtctldata_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7754,7 +7891,7 @@ func (x *GetTransactionInfoResponse) String() string { func (*GetTransactionInfoResponse) ProtoMessage() {} func (x *GetTransactionInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[121] + mi := &file_vtctldata_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7767,7 +7904,7 @@ func (x *GetTransactionInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTransactionInfoResponse.ProtoReflect.Descriptor instead. func (*GetTransactionInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{121} + return file_vtctldata_proto_rawDescGZIP(), []int{123} } func (x *GetTransactionInfoResponse) GetMetadata() *query.TransactionMetadata { @@ -7795,7 +7932,7 @@ type ConcludeTransactionRequest struct { func (x *ConcludeTransactionRequest) Reset() { *x = ConcludeTransactionRequest{} - mi := &file_vtctldata_proto_msgTypes[122] + mi := &file_vtctldata_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7807,7 +7944,7 @@ func (x *ConcludeTransactionRequest) String() string { func (*ConcludeTransactionRequest) ProtoMessage() {} func (x *ConcludeTransactionRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[122] + mi := &file_vtctldata_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7820,7 +7957,7 @@ func (x *ConcludeTransactionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConcludeTransactionRequest.ProtoReflect.Descriptor instead. func (*ConcludeTransactionRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{122} + return file_vtctldata_proto_rawDescGZIP(), []int{124} } func (x *ConcludeTransactionRequest) GetDtid() string { @@ -7845,7 +7982,7 @@ type ConcludeTransactionResponse struct { func (x *ConcludeTransactionResponse) Reset() { *x = ConcludeTransactionResponse{} - mi := &file_vtctldata_proto_msgTypes[123] + mi := &file_vtctldata_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7857,7 +7994,7 @@ func (x *ConcludeTransactionResponse) String() string { func (*ConcludeTransactionResponse) ProtoMessage() {} func (x *ConcludeTransactionResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[123] + mi := &file_vtctldata_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7870,7 +8007,7 @@ func (x *ConcludeTransactionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ConcludeTransactionResponse.ProtoReflect.Descriptor instead. func (*ConcludeTransactionResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{123} + return file_vtctldata_proto_rawDescGZIP(), []int{125} } type GetVSchemaRequest struct { @@ -7883,7 +8020,7 @@ type GetVSchemaRequest struct { func (x *GetVSchemaRequest) Reset() { *x = GetVSchemaRequest{} - mi := &file_vtctldata_proto_msgTypes[124] + mi := &file_vtctldata_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7895,7 +8032,7 @@ func (x *GetVSchemaRequest) String() string { func (*GetVSchemaRequest) ProtoMessage() {} func (x *GetVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[124] + mi := &file_vtctldata_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7908,7 +8045,7 @@ func (x *GetVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVSchemaRequest.ProtoReflect.Descriptor instead. func (*GetVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{124} + return file_vtctldata_proto_rawDescGZIP(), []int{126} } func (x *GetVSchemaRequest) GetKeyspace() string { @@ -7928,7 +8065,7 @@ type GetVersionRequest struct { func (x *GetVersionRequest) Reset() { *x = GetVersionRequest{} - mi := &file_vtctldata_proto_msgTypes[125] + mi := &file_vtctldata_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7940,7 +8077,7 @@ func (x *GetVersionRequest) String() string { func (*GetVersionRequest) ProtoMessage() {} func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[125] + mi := &file_vtctldata_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7953,7 +8090,7 @@ func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVersionRequest.ProtoReflect.Descriptor instead. func (*GetVersionRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{125} + return file_vtctldata_proto_rawDescGZIP(), []int{127} } func (x *GetVersionRequest) GetTabletAlias() *topodata.TabletAlias { @@ -7973,7 +8110,7 @@ type GetVersionResponse struct { func (x *GetVersionResponse) Reset() { *x = GetVersionResponse{} - mi := &file_vtctldata_proto_msgTypes[126] + mi := &file_vtctldata_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7985,7 +8122,7 @@ func (x *GetVersionResponse) String() string { func (*GetVersionResponse) ProtoMessage() {} func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[126] + mi := &file_vtctldata_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7998,7 +8135,7 @@ func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVersionResponse.ProtoReflect.Descriptor instead. func (*GetVersionResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{126} + return file_vtctldata_proto_rawDescGZIP(), []int{128} } func (x *GetVersionResponse) GetVersion() string { @@ -8018,7 +8155,7 @@ type GetVSchemaResponse struct { func (x *GetVSchemaResponse) Reset() { *x = GetVSchemaResponse{} - mi := &file_vtctldata_proto_msgTypes[127] + mi := &file_vtctldata_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8030,7 +8167,7 @@ func (x *GetVSchemaResponse) String() string { func (*GetVSchemaResponse) ProtoMessage() {} func (x *GetVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[127] + mi := &file_vtctldata_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8043,7 +8180,7 @@ func (x *GetVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVSchemaResponse.ProtoReflect.Descriptor instead. func (*GetVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{127} + return file_vtctldata_proto_rawDescGZIP(), []int{129} } func (x *GetVSchemaResponse) GetVSchema() *vschema.Keyspace { @@ -8069,7 +8206,7 @@ type GetWorkflowsRequest struct { func (x *GetWorkflowsRequest) Reset() { *x = GetWorkflowsRequest{} - mi := &file_vtctldata_proto_msgTypes[128] + mi := &file_vtctldata_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8081,7 +8218,7 @@ func (x *GetWorkflowsRequest) String() string { func (*GetWorkflowsRequest) ProtoMessage() {} func (x *GetWorkflowsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[128] + mi := &file_vtctldata_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8094,7 +8231,7 @@ func (x *GetWorkflowsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkflowsRequest.ProtoReflect.Descriptor instead. func (*GetWorkflowsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{128} + return file_vtctldata_proto_rawDescGZIP(), []int{130} } func (x *GetWorkflowsRequest) GetKeyspace() string { @@ -8149,7 +8286,7 @@ type GetWorkflowsResponse struct { func (x *GetWorkflowsResponse) Reset() { *x = GetWorkflowsResponse{} - mi := &file_vtctldata_proto_msgTypes[129] + mi := &file_vtctldata_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8161,7 +8298,7 @@ func (x *GetWorkflowsResponse) String() string { func (*GetWorkflowsResponse) ProtoMessage() {} func (x *GetWorkflowsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[129] + mi := &file_vtctldata_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8174,7 +8311,7 @@ func (x *GetWorkflowsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkflowsResponse.ProtoReflect.Descriptor instead. func (*GetWorkflowsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{129} + return file_vtctldata_proto_rawDescGZIP(), []int{131} } func (x *GetWorkflowsResponse) GetWorkflows() []*Workflow { @@ -8198,7 +8335,7 @@ type InitShardPrimaryRequest struct { func (x *InitShardPrimaryRequest) Reset() { *x = InitShardPrimaryRequest{} - mi := &file_vtctldata_proto_msgTypes[130] + mi := &file_vtctldata_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8210,7 +8347,7 @@ func (x *InitShardPrimaryRequest) String() string { func (*InitShardPrimaryRequest) ProtoMessage() {} func (x *InitShardPrimaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[130] + mi := &file_vtctldata_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8223,7 +8360,7 @@ func (x *InitShardPrimaryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InitShardPrimaryRequest.ProtoReflect.Descriptor instead. func (*InitShardPrimaryRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{130} + return file_vtctldata_proto_rawDescGZIP(), []int{132} } func (x *InitShardPrimaryRequest) GetKeyspace() string { @@ -8271,7 +8408,7 @@ type InitShardPrimaryResponse struct { func (x *InitShardPrimaryResponse) Reset() { *x = InitShardPrimaryResponse{} - mi := &file_vtctldata_proto_msgTypes[131] + mi := &file_vtctldata_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8283,7 +8420,7 @@ func (x *InitShardPrimaryResponse) String() string { func (*InitShardPrimaryResponse) ProtoMessage() {} func (x *InitShardPrimaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[131] + mi := &file_vtctldata_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8296,7 +8433,7 @@ func (x *InitShardPrimaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InitShardPrimaryResponse.ProtoReflect.Descriptor instead. func (*InitShardPrimaryResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{131} + return file_vtctldata_proto_rawDescGZIP(), []int{133} } func (x *InitShardPrimaryResponse) GetEvents() []*logutil.Event { @@ -8317,7 +8454,7 @@ type LaunchSchemaMigrationRequest struct { func (x *LaunchSchemaMigrationRequest) Reset() { *x = LaunchSchemaMigrationRequest{} - mi := &file_vtctldata_proto_msgTypes[132] + mi := &file_vtctldata_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8329,7 +8466,7 @@ func (x *LaunchSchemaMigrationRequest) String() string { func (*LaunchSchemaMigrationRequest) ProtoMessage() {} func (x *LaunchSchemaMigrationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[132] + mi := &file_vtctldata_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8342,7 +8479,7 @@ func (x *LaunchSchemaMigrationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LaunchSchemaMigrationRequest.ProtoReflect.Descriptor instead. func (*LaunchSchemaMigrationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{132} + return file_vtctldata_proto_rawDescGZIP(), []int{134} } func (x *LaunchSchemaMigrationRequest) GetKeyspace() string { @@ -8369,7 +8506,7 @@ type LaunchSchemaMigrationResponse struct { func (x *LaunchSchemaMigrationResponse) Reset() { *x = LaunchSchemaMigrationResponse{} - mi := &file_vtctldata_proto_msgTypes[133] + mi := &file_vtctldata_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8381,7 +8518,7 @@ func (x *LaunchSchemaMigrationResponse) String() string { func (*LaunchSchemaMigrationResponse) ProtoMessage() {} func (x *LaunchSchemaMigrationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[133] + mi := &file_vtctldata_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8394,7 +8531,7 @@ func (x *LaunchSchemaMigrationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LaunchSchemaMigrationResponse.ProtoReflect.Descriptor instead. func (*LaunchSchemaMigrationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{133} + return file_vtctldata_proto_rawDescGZIP(), []int{135} } func (x *LaunchSchemaMigrationResponse) GetRowsAffectedByShard() map[string]uint64 { @@ -8404,6 +8541,106 @@ func (x *LaunchSchemaMigrationResponse) GetRowsAffectedByShard() map[string]uint return nil } +type LookupVindexCompleteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Where the lookup vindex lives. + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // This is the name of the lookup vindex and the vreplication workflow. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Where the vreplication workflow lives. + TableKeyspace string `protobuf:"bytes,3,opt,name=table_keyspace,json=tableKeyspace,proto3" json:"table_keyspace,omitempty"` +} + +func (x *LookupVindexCompleteRequest) Reset() { + *x = LookupVindexCompleteRequest{} + mi := &file_vtctldata_proto_msgTypes[136] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LookupVindexCompleteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LookupVindexCompleteRequest) ProtoMessage() {} + +func (x *LookupVindexCompleteRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[136] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LookupVindexCompleteRequest.ProtoReflect.Descriptor instead. +func (*LookupVindexCompleteRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{136} +} + +func (x *LookupVindexCompleteRequest) GetKeyspace() string { + if x != nil { + return x.Keyspace + } + return "" +} + +func (x *LookupVindexCompleteRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *LookupVindexCompleteRequest) GetTableKeyspace() string { + if x != nil { + return x.TableKeyspace + } + return "" +} + +type LookupVindexCompleteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *LookupVindexCompleteResponse) Reset() { + *x = LookupVindexCompleteResponse{} + mi := &file_vtctldata_proto_msgTypes[137] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LookupVindexCompleteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LookupVindexCompleteResponse) ProtoMessage() {} + +func (x *LookupVindexCompleteResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[137] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LookupVindexCompleteResponse.ProtoReflect.Descriptor instead. +func (*LookupVindexCompleteResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{137} +} + type LookupVindexCreateRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -8420,7 +8657,7 @@ type LookupVindexCreateRequest struct { func (x *LookupVindexCreateRequest) Reset() { *x = LookupVindexCreateRequest{} - mi := &file_vtctldata_proto_msgTypes[134] + mi := &file_vtctldata_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8432,7 +8669,7 @@ func (x *LookupVindexCreateRequest) String() string { func (*LookupVindexCreateRequest) ProtoMessage() {} func (x *LookupVindexCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[134] + mi := &file_vtctldata_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8445,7 +8682,7 @@ func (x *LookupVindexCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexCreateRequest.ProtoReflect.Descriptor instead. func (*LookupVindexCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{134} + return file_vtctldata_proto_rawDescGZIP(), []int{138} } func (x *LookupVindexCreateRequest) GetKeyspace() string { @@ -8505,7 +8742,7 @@ type LookupVindexCreateResponse struct { func (x *LookupVindexCreateResponse) Reset() { *x = LookupVindexCreateResponse{} - mi := &file_vtctldata_proto_msgTypes[135] + mi := &file_vtctldata_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8517,7 +8754,7 @@ func (x *LookupVindexCreateResponse) String() string { func (*LookupVindexCreateResponse) ProtoMessage() {} func (x *LookupVindexCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[135] + mi := &file_vtctldata_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8530,7 +8767,7 @@ func (x *LookupVindexCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexCreateResponse.ProtoReflect.Descriptor instead. func (*LookupVindexCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{135} + return file_vtctldata_proto_rawDescGZIP(), []int{139} } type LookupVindexExternalizeRequest struct { @@ -8544,11 +8781,14 @@ type LookupVindexExternalizeRequest struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Where the vreplication workflow lives. TableKeyspace string `protobuf:"bytes,3,opt,name=table_keyspace,json=tableKeyspace,proto3" json:"table_keyspace,omitempty"` + // If this is set true, we directly delete the workflow instead of stopping. + // Also, complete command is not required to delete workflow in that case. + DeleteWorkflow bool `protobuf:"varint,4,opt,name=delete_workflow,json=deleteWorkflow,proto3" json:"delete_workflow,omitempty"` } func (x *LookupVindexExternalizeRequest) Reset() { *x = LookupVindexExternalizeRequest{} - mi := &file_vtctldata_proto_msgTypes[136] + mi := &file_vtctldata_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8560,7 +8800,7 @@ func (x *LookupVindexExternalizeRequest) String() string { func (*LookupVindexExternalizeRequest) ProtoMessage() {} func (x *LookupVindexExternalizeRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[136] + mi := &file_vtctldata_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8573,7 +8813,7 @@ func (x *LookupVindexExternalizeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexExternalizeRequest.ProtoReflect.Descriptor instead. func (*LookupVindexExternalizeRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{136} + return file_vtctldata_proto_rawDescGZIP(), []int{140} } func (x *LookupVindexExternalizeRequest) GetKeyspace() string { @@ -8597,18 +8837,27 @@ func (x *LookupVindexExternalizeRequest) GetTableKeyspace() string { return "" } +func (x *LookupVindexExternalizeRequest) GetDeleteWorkflow() bool { + if x != nil { + return x.DeleteWorkflow + } + return false +} + type LookupVindexExternalizeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Was the workflow also deleted. - WorkflowDeleted bool `protobuf:"varint,1,opt,name=workflow_deleted,json=workflowDeleted,proto3" json:"workflow_deleted,omitempty"` + // Was the workflow stopped. + WorkflowStopped bool `protobuf:"varint,1,opt,name=workflow_stopped,json=workflowStopped,proto3" json:"workflow_stopped,omitempty"` + // Was the workflow deleted. + WorkflowDeleted bool `protobuf:"varint,2,opt,name=workflow_deleted,json=workflowDeleted,proto3" json:"workflow_deleted,omitempty"` } func (x *LookupVindexExternalizeResponse) Reset() { *x = LookupVindexExternalizeResponse{} - mi := &file_vtctldata_proto_msgTypes[137] + mi := &file_vtctldata_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8620,7 +8869,7 @@ func (x *LookupVindexExternalizeResponse) String() string { func (*LookupVindexExternalizeResponse) ProtoMessage() {} func (x *LookupVindexExternalizeResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[137] + mi := &file_vtctldata_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8633,7 +8882,14 @@ func (x *LookupVindexExternalizeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexExternalizeResponse.ProtoReflect.Descriptor instead. func (*LookupVindexExternalizeResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{137} + return file_vtctldata_proto_rawDescGZIP(), []int{141} +} + +func (x *LookupVindexExternalizeResponse) GetWorkflowStopped() bool { + if x != nil { + return x.WorkflowStopped + } + return false } func (x *LookupVindexExternalizeResponse) GetWorkflowDeleted() bool { @@ -8643,6 +8899,106 @@ func (x *LookupVindexExternalizeResponse) GetWorkflowDeleted() bool { return false } +type LookupVindexInternalizeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Where the lookup vindex lives. + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // This is the name of the lookup vindex and the vreplication workflow. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Where the vreplication workflow lives. + TableKeyspace string `protobuf:"bytes,3,opt,name=table_keyspace,json=tableKeyspace,proto3" json:"table_keyspace,omitempty"` +} + +func (x *LookupVindexInternalizeRequest) Reset() { + *x = LookupVindexInternalizeRequest{} + mi := &file_vtctldata_proto_msgTypes[142] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LookupVindexInternalizeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LookupVindexInternalizeRequest) ProtoMessage() {} + +func (x *LookupVindexInternalizeRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[142] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LookupVindexInternalizeRequest.ProtoReflect.Descriptor instead. +func (*LookupVindexInternalizeRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{142} +} + +func (x *LookupVindexInternalizeRequest) GetKeyspace() string { + if x != nil { + return x.Keyspace + } + return "" +} + +func (x *LookupVindexInternalizeRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *LookupVindexInternalizeRequest) GetTableKeyspace() string { + if x != nil { + return x.TableKeyspace + } + return "" +} + +type LookupVindexInternalizeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *LookupVindexInternalizeResponse) Reset() { + *x = LookupVindexInternalizeResponse{} + mi := &file_vtctldata_proto_msgTypes[143] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LookupVindexInternalizeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LookupVindexInternalizeResponse) ProtoMessage() {} + +func (x *LookupVindexInternalizeResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[143] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LookupVindexInternalizeResponse.ProtoReflect.Descriptor instead. +func (*LookupVindexInternalizeResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{143} +} + type MaterializeCreateRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -8653,7 +9009,7 @@ type MaterializeCreateRequest struct { func (x *MaterializeCreateRequest) Reset() { *x = MaterializeCreateRequest{} - mi := &file_vtctldata_proto_msgTypes[138] + mi := &file_vtctldata_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8665,7 +9021,7 @@ func (x *MaterializeCreateRequest) String() string { func (*MaterializeCreateRequest) ProtoMessage() {} func (x *MaterializeCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[138] + mi := &file_vtctldata_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8678,7 +9034,7 @@ func (x *MaterializeCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MaterializeCreateRequest.ProtoReflect.Descriptor instead. func (*MaterializeCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{138} + return file_vtctldata_proto_rawDescGZIP(), []int{144} } func (x *MaterializeCreateRequest) GetSettings() *MaterializeSettings { @@ -8696,7 +9052,7 @@ type MaterializeCreateResponse struct { func (x *MaterializeCreateResponse) Reset() { *x = MaterializeCreateResponse{} - mi := &file_vtctldata_proto_msgTypes[139] + mi := &file_vtctldata_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8708,7 +9064,7 @@ func (x *MaterializeCreateResponse) String() string { func (*MaterializeCreateResponse) ProtoMessage() {} func (x *MaterializeCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[139] + mi := &file_vtctldata_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8721,7 +9077,7 @@ func (x *MaterializeCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MaterializeCreateResponse.ProtoReflect.Descriptor instead. func (*MaterializeCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{139} + return file_vtctldata_proto_rawDescGZIP(), []int{145} } type MigrateCreateRequest struct { @@ -8759,7 +9115,7 @@ type MigrateCreateRequest struct { func (x *MigrateCreateRequest) Reset() { *x = MigrateCreateRequest{} - mi := &file_vtctldata_proto_msgTypes[140] + mi := &file_vtctldata_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8771,7 +9127,7 @@ func (x *MigrateCreateRequest) String() string { func (*MigrateCreateRequest) ProtoMessage() {} func (x *MigrateCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[140] + mi := &file_vtctldata_proto_msgTypes[146] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8784,7 +9140,7 @@ func (x *MigrateCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrateCreateRequest.ProtoReflect.Descriptor instead. func (*MigrateCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{140} + return file_vtctldata_proto_rawDescGZIP(), []int{146} } func (x *MigrateCreateRequest) GetWorkflow() string { @@ -8921,7 +9277,7 @@ type MigrateCompleteRequest struct { func (x *MigrateCompleteRequest) Reset() { *x = MigrateCompleteRequest{} - mi := &file_vtctldata_proto_msgTypes[141] + mi := &file_vtctldata_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8933,7 +9289,7 @@ func (x *MigrateCompleteRequest) String() string { func (*MigrateCompleteRequest) ProtoMessage() {} func (x *MigrateCompleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[141] + mi := &file_vtctldata_proto_msgTypes[147] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8946,7 +9302,7 @@ func (x *MigrateCompleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrateCompleteRequest.ProtoReflect.Descriptor instead. func (*MigrateCompleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{141} + return file_vtctldata_proto_rawDescGZIP(), []int{147} } func (x *MigrateCompleteRequest) GetWorkflow() string { @@ -9002,7 +9358,7 @@ type MigrateCompleteResponse struct { func (x *MigrateCompleteResponse) Reset() { *x = MigrateCompleteResponse{} - mi := &file_vtctldata_proto_msgTypes[142] + mi := &file_vtctldata_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9014,7 +9370,7 @@ func (x *MigrateCompleteResponse) String() string { func (*MigrateCompleteResponse) ProtoMessage() {} func (x *MigrateCompleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[142] + mi := &file_vtctldata_proto_msgTypes[148] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9027,7 +9383,7 @@ func (x *MigrateCompleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrateCompleteResponse.ProtoReflect.Descriptor instead. func (*MigrateCompleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{142} + return file_vtctldata_proto_rawDescGZIP(), []int{148} } func (x *MigrateCompleteResponse) GetSummary() string { @@ -9057,7 +9413,7 @@ type MountRegisterRequest struct { func (x *MountRegisterRequest) Reset() { *x = MountRegisterRequest{} - mi := &file_vtctldata_proto_msgTypes[143] + mi := &file_vtctldata_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9069,7 +9425,7 @@ func (x *MountRegisterRequest) String() string { func (*MountRegisterRequest) ProtoMessage() {} func (x *MountRegisterRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[143] + mi := &file_vtctldata_proto_msgTypes[149] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9082,7 +9438,7 @@ func (x *MountRegisterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountRegisterRequest.ProtoReflect.Descriptor instead. func (*MountRegisterRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{143} + return file_vtctldata_proto_rawDescGZIP(), []int{149} } func (x *MountRegisterRequest) GetTopoType() string { @@ -9121,7 +9477,7 @@ type MountRegisterResponse struct { func (x *MountRegisterResponse) Reset() { *x = MountRegisterResponse{} - mi := &file_vtctldata_proto_msgTypes[144] + mi := &file_vtctldata_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9133,7 +9489,7 @@ func (x *MountRegisterResponse) String() string { func (*MountRegisterResponse) ProtoMessage() {} func (x *MountRegisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[144] + mi := &file_vtctldata_proto_msgTypes[150] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9146,7 +9502,7 @@ func (x *MountRegisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountRegisterResponse.ProtoReflect.Descriptor instead. func (*MountRegisterResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{144} + return file_vtctldata_proto_rawDescGZIP(), []int{150} } type MountUnregisterRequest struct { @@ -9159,7 +9515,7 @@ type MountUnregisterRequest struct { func (x *MountUnregisterRequest) Reset() { *x = MountUnregisterRequest{} - mi := &file_vtctldata_proto_msgTypes[145] + mi := &file_vtctldata_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9171,7 +9527,7 @@ func (x *MountUnregisterRequest) String() string { func (*MountUnregisterRequest) ProtoMessage() {} func (x *MountUnregisterRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[145] + mi := &file_vtctldata_proto_msgTypes[151] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9184,7 +9540,7 @@ func (x *MountUnregisterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountUnregisterRequest.ProtoReflect.Descriptor instead. func (*MountUnregisterRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{145} + return file_vtctldata_proto_rawDescGZIP(), []int{151} } func (x *MountUnregisterRequest) GetName() string { @@ -9202,7 +9558,7 @@ type MountUnregisterResponse struct { func (x *MountUnregisterResponse) Reset() { *x = MountUnregisterResponse{} - mi := &file_vtctldata_proto_msgTypes[146] + mi := &file_vtctldata_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9214,7 +9570,7 @@ func (x *MountUnregisterResponse) String() string { func (*MountUnregisterResponse) ProtoMessage() {} func (x *MountUnregisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[146] + mi := &file_vtctldata_proto_msgTypes[152] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9227,7 +9583,7 @@ func (x *MountUnregisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountUnregisterResponse.ProtoReflect.Descriptor instead. func (*MountUnregisterResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{146} + return file_vtctldata_proto_rawDescGZIP(), []int{152} } type MountShowRequest struct { @@ -9240,7 +9596,7 @@ type MountShowRequest struct { func (x *MountShowRequest) Reset() { *x = MountShowRequest{} - mi := &file_vtctldata_proto_msgTypes[147] + mi := &file_vtctldata_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9252,7 +9608,7 @@ func (x *MountShowRequest) String() string { func (*MountShowRequest) ProtoMessage() {} func (x *MountShowRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[147] + mi := &file_vtctldata_proto_msgTypes[153] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9265,7 +9621,7 @@ func (x *MountShowRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountShowRequest.ProtoReflect.Descriptor instead. func (*MountShowRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{147} + return file_vtctldata_proto_rawDescGZIP(), []int{153} } func (x *MountShowRequest) GetName() string { @@ -9288,7 +9644,7 @@ type MountShowResponse struct { func (x *MountShowResponse) Reset() { *x = MountShowResponse{} - mi := &file_vtctldata_proto_msgTypes[148] + mi := &file_vtctldata_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9300,7 +9656,7 @@ func (x *MountShowResponse) String() string { func (*MountShowResponse) ProtoMessage() {} func (x *MountShowResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[148] + mi := &file_vtctldata_proto_msgTypes[154] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9313,7 +9669,7 @@ func (x *MountShowResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountShowResponse.ProtoReflect.Descriptor instead. func (*MountShowResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{148} + return file_vtctldata_proto_rawDescGZIP(), []int{154} } func (x *MountShowResponse) GetTopoType() string { @@ -9352,7 +9708,7 @@ type MountListRequest struct { func (x *MountListRequest) Reset() { *x = MountListRequest{} - mi := &file_vtctldata_proto_msgTypes[149] + mi := &file_vtctldata_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9364,7 +9720,7 @@ func (x *MountListRequest) String() string { func (*MountListRequest) ProtoMessage() {} func (x *MountListRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[149] + mi := &file_vtctldata_proto_msgTypes[155] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9377,7 +9733,7 @@ func (x *MountListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountListRequest.ProtoReflect.Descriptor instead. func (*MountListRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{149} + return file_vtctldata_proto_rawDescGZIP(), []int{155} } type MountListResponse struct { @@ -9390,7 +9746,7 @@ type MountListResponse struct { func (x *MountListResponse) Reset() { *x = MountListResponse{} - mi := &file_vtctldata_proto_msgTypes[150] + mi := &file_vtctldata_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9402,7 +9758,7 @@ func (x *MountListResponse) String() string { func (*MountListResponse) ProtoMessage() {} func (x *MountListResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[150] + mi := &file_vtctldata_proto_msgTypes[156] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9415,7 +9771,7 @@ func (x *MountListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountListResponse.ProtoReflect.Descriptor instead. func (*MountListResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{150} + return file_vtctldata_proto_rawDescGZIP(), []int{156} } func (x *MountListResponse) GetNames() []string { @@ -9465,7 +9821,7 @@ type MoveTablesCreateRequest struct { func (x *MoveTablesCreateRequest) Reset() { *x = MoveTablesCreateRequest{} - mi := &file_vtctldata_proto_msgTypes[151] + mi := &file_vtctldata_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9477,7 +9833,7 @@ func (x *MoveTablesCreateRequest) String() string { func (*MoveTablesCreateRequest) ProtoMessage() {} func (x *MoveTablesCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[151] + mi := &file_vtctldata_proto_msgTypes[157] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9490,7 +9846,7 @@ func (x *MoveTablesCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCreateRequest.ProtoReflect.Descriptor instead. func (*MoveTablesCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{151} + return file_vtctldata_proto_rawDescGZIP(), []int{157} } func (x *MoveTablesCreateRequest) GetWorkflow() string { @@ -9644,7 +10000,7 @@ type MoveTablesCreateResponse struct { func (x *MoveTablesCreateResponse) Reset() { *x = MoveTablesCreateResponse{} - mi := &file_vtctldata_proto_msgTypes[152] + mi := &file_vtctldata_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9656,7 +10012,7 @@ func (x *MoveTablesCreateResponse) String() string { func (*MoveTablesCreateResponse) ProtoMessage() {} func (x *MoveTablesCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[152] + mi := &file_vtctldata_proto_msgTypes[158] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9669,7 +10025,7 @@ func (x *MoveTablesCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCreateResponse.ProtoReflect.Descriptor instead. func (*MoveTablesCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{152} + return file_vtctldata_proto_rawDescGZIP(), []int{158} } func (x *MoveTablesCreateResponse) GetSummary() string { @@ -9702,7 +10058,7 @@ type MoveTablesCompleteRequest struct { func (x *MoveTablesCompleteRequest) Reset() { *x = MoveTablesCompleteRequest{} - mi := &file_vtctldata_proto_msgTypes[153] + mi := &file_vtctldata_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9714,7 +10070,7 @@ func (x *MoveTablesCompleteRequest) String() string { func (*MoveTablesCompleteRequest) ProtoMessage() {} func (x *MoveTablesCompleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[153] + mi := &file_vtctldata_proto_msgTypes[159] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9727,7 +10083,7 @@ func (x *MoveTablesCompleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCompleteRequest.ProtoReflect.Descriptor instead. func (*MoveTablesCompleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{153} + return file_vtctldata_proto_rawDescGZIP(), []int{159} } func (x *MoveTablesCompleteRequest) GetWorkflow() string { @@ -9790,7 +10146,7 @@ type MoveTablesCompleteResponse struct { func (x *MoveTablesCompleteResponse) Reset() { *x = MoveTablesCompleteResponse{} - mi := &file_vtctldata_proto_msgTypes[154] + mi := &file_vtctldata_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9802,7 +10158,7 @@ func (x *MoveTablesCompleteResponse) String() string { func (*MoveTablesCompleteResponse) ProtoMessage() {} func (x *MoveTablesCompleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[154] + mi := &file_vtctldata_proto_msgTypes[160] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9815,7 +10171,7 @@ func (x *MoveTablesCompleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCompleteResponse.ProtoReflect.Descriptor instead. func (*MoveTablesCompleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{154} + return file_vtctldata_proto_rawDescGZIP(), []int{160} } func (x *MoveTablesCompleteResponse) GetSummary() string { @@ -9842,7 +10198,7 @@ type PingTabletRequest struct { func (x *PingTabletRequest) Reset() { *x = PingTabletRequest{} - mi := &file_vtctldata_proto_msgTypes[155] + mi := &file_vtctldata_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9854,7 +10210,7 @@ func (x *PingTabletRequest) String() string { func (*PingTabletRequest) ProtoMessage() {} func (x *PingTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[155] + mi := &file_vtctldata_proto_msgTypes[161] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9867,7 +10223,7 @@ func (x *PingTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PingTabletRequest.ProtoReflect.Descriptor instead. func (*PingTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{155} + return file_vtctldata_proto_rawDescGZIP(), []int{161} } func (x *PingTabletRequest) GetTabletAlias() *topodata.TabletAlias { @@ -9885,7 +10241,7 @@ type PingTabletResponse struct { func (x *PingTabletResponse) Reset() { *x = PingTabletResponse{} - mi := &file_vtctldata_proto_msgTypes[156] + mi := &file_vtctldata_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9897,7 +10253,7 @@ func (x *PingTabletResponse) String() string { func (*PingTabletResponse) ProtoMessage() {} func (x *PingTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[156] + mi := &file_vtctldata_proto_msgTypes[162] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9910,7 +10266,7 @@ func (x *PingTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PingTabletResponse.ProtoReflect.Descriptor instead. func (*PingTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{156} + return file_vtctldata_proto_rawDescGZIP(), []int{162} } type PlannedReparentShardRequest struct { @@ -9953,7 +10309,7 @@ type PlannedReparentShardRequest struct { func (x *PlannedReparentShardRequest) Reset() { *x = PlannedReparentShardRequest{} - mi := &file_vtctldata_proto_msgTypes[157] + mi := &file_vtctldata_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9965,7 +10321,7 @@ func (x *PlannedReparentShardRequest) String() string { func (*PlannedReparentShardRequest) ProtoMessage() {} func (x *PlannedReparentShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[157] + mi := &file_vtctldata_proto_msgTypes[163] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9978,7 +10334,7 @@ func (x *PlannedReparentShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedReparentShardRequest.ProtoReflect.Descriptor instead. func (*PlannedReparentShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{157} + return file_vtctldata_proto_rawDescGZIP(), []int{163} } func (x *PlannedReparentShardRequest) GetKeyspace() string { @@ -10056,7 +10412,7 @@ type PlannedReparentShardResponse struct { func (x *PlannedReparentShardResponse) Reset() { *x = PlannedReparentShardResponse{} - mi := &file_vtctldata_proto_msgTypes[158] + mi := &file_vtctldata_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10068,7 +10424,7 @@ func (x *PlannedReparentShardResponse) String() string { func (*PlannedReparentShardResponse) ProtoMessage() {} func (x *PlannedReparentShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[158] + mi := &file_vtctldata_proto_msgTypes[164] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10081,7 +10437,7 @@ func (x *PlannedReparentShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedReparentShardResponse.ProtoReflect.Descriptor instead. func (*PlannedReparentShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{158} + return file_vtctldata_proto_rawDescGZIP(), []int{164} } func (x *PlannedReparentShardResponse) GetKeyspace() string { @@ -10126,7 +10482,7 @@ type RebuildKeyspaceGraphRequest struct { func (x *RebuildKeyspaceGraphRequest) Reset() { *x = RebuildKeyspaceGraphRequest{} - mi := &file_vtctldata_proto_msgTypes[159] + mi := &file_vtctldata_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10138,7 +10494,7 @@ func (x *RebuildKeyspaceGraphRequest) String() string { func (*RebuildKeyspaceGraphRequest) ProtoMessage() {} func (x *RebuildKeyspaceGraphRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[159] + mi := &file_vtctldata_proto_msgTypes[165] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10151,7 +10507,7 @@ func (x *RebuildKeyspaceGraphRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildKeyspaceGraphRequest.ProtoReflect.Descriptor instead. func (*RebuildKeyspaceGraphRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{159} + return file_vtctldata_proto_rawDescGZIP(), []int{165} } func (x *RebuildKeyspaceGraphRequest) GetKeyspace() string { @@ -10183,7 +10539,7 @@ type RebuildKeyspaceGraphResponse struct { func (x *RebuildKeyspaceGraphResponse) Reset() { *x = RebuildKeyspaceGraphResponse{} - mi := &file_vtctldata_proto_msgTypes[160] + mi := &file_vtctldata_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10195,7 +10551,7 @@ func (x *RebuildKeyspaceGraphResponse) String() string { func (*RebuildKeyspaceGraphResponse) ProtoMessage() {} func (x *RebuildKeyspaceGraphResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[160] + mi := &file_vtctldata_proto_msgTypes[166] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10208,7 +10564,7 @@ func (x *RebuildKeyspaceGraphResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildKeyspaceGraphResponse.ProtoReflect.Descriptor instead. func (*RebuildKeyspaceGraphResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{160} + return file_vtctldata_proto_rawDescGZIP(), []int{166} } type RebuildVSchemaGraphRequest struct { @@ -10223,7 +10579,7 @@ type RebuildVSchemaGraphRequest struct { func (x *RebuildVSchemaGraphRequest) Reset() { *x = RebuildVSchemaGraphRequest{} - mi := &file_vtctldata_proto_msgTypes[161] + mi := &file_vtctldata_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10235,7 +10591,7 @@ func (x *RebuildVSchemaGraphRequest) String() string { func (*RebuildVSchemaGraphRequest) ProtoMessage() {} func (x *RebuildVSchemaGraphRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[161] + mi := &file_vtctldata_proto_msgTypes[167] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10248,7 +10604,7 @@ func (x *RebuildVSchemaGraphRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildVSchemaGraphRequest.ProtoReflect.Descriptor instead. func (*RebuildVSchemaGraphRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{161} + return file_vtctldata_proto_rawDescGZIP(), []int{167} } func (x *RebuildVSchemaGraphRequest) GetCells() []string { @@ -10266,7 +10622,7 @@ type RebuildVSchemaGraphResponse struct { func (x *RebuildVSchemaGraphResponse) Reset() { *x = RebuildVSchemaGraphResponse{} - mi := &file_vtctldata_proto_msgTypes[162] + mi := &file_vtctldata_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10278,7 +10634,7 @@ func (x *RebuildVSchemaGraphResponse) String() string { func (*RebuildVSchemaGraphResponse) ProtoMessage() {} func (x *RebuildVSchemaGraphResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[162] + mi := &file_vtctldata_proto_msgTypes[168] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10291,7 +10647,7 @@ func (x *RebuildVSchemaGraphResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildVSchemaGraphResponse.ProtoReflect.Descriptor instead. func (*RebuildVSchemaGraphResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{162} + return file_vtctldata_proto_rawDescGZIP(), []int{168} } type RefreshStateRequest struct { @@ -10304,7 +10660,7 @@ type RefreshStateRequest struct { func (x *RefreshStateRequest) Reset() { *x = RefreshStateRequest{} - mi := &file_vtctldata_proto_msgTypes[163] + mi := &file_vtctldata_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10316,7 +10672,7 @@ func (x *RefreshStateRequest) String() string { func (*RefreshStateRequest) ProtoMessage() {} func (x *RefreshStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[163] + mi := &file_vtctldata_proto_msgTypes[169] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10329,7 +10685,7 @@ func (x *RefreshStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateRequest.ProtoReflect.Descriptor instead. func (*RefreshStateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{163} + return file_vtctldata_proto_rawDescGZIP(), []int{169} } func (x *RefreshStateRequest) GetTabletAlias() *topodata.TabletAlias { @@ -10347,7 +10703,7 @@ type RefreshStateResponse struct { func (x *RefreshStateResponse) Reset() { *x = RefreshStateResponse{} - mi := &file_vtctldata_proto_msgTypes[164] + mi := &file_vtctldata_proto_msgTypes[170] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10359,7 +10715,7 @@ func (x *RefreshStateResponse) String() string { func (*RefreshStateResponse) ProtoMessage() {} func (x *RefreshStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[164] + mi := &file_vtctldata_proto_msgTypes[170] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10372,7 +10728,7 @@ func (x *RefreshStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateResponse.ProtoReflect.Descriptor instead. func (*RefreshStateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{164} + return file_vtctldata_proto_rawDescGZIP(), []int{170} } type RefreshStateByShardRequest struct { @@ -10387,7 +10743,7 @@ type RefreshStateByShardRequest struct { func (x *RefreshStateByShardRequest) Reset() { *x = RefreshStateByShardRequest{} - mi := &file_vtctldata_proto_msgTypes[165] + mi := &file_vtctldata_proto_msgTypes[171] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10399,7 +10755,7 @@ func (x *RefreshStateByShardRequest) String() string { func (*RefreshStateByShardRequest) ProtoMessage() {} func (x *RefreshStateByShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[165] + mi := &file_vtctldata_proto_msgTypes[171] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10412,7 +10768,7 @@ func (x *RefreshStateByShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateByShardRequest.ProtoReflect.Descriptor instead. func (*RefreshStateByShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{165} + return file_vtctldata_proto_rawDescGZIP(), []int{171} } func (x *RefreshStateByShardRequest) GetKeyspace() string { @@ -10448,7 +10804,7 @@ type RefreshStateByShardResponse struct { func (x *RefreshStateByShardResponse) Reset() { *x = RefreshStateByShardResponse{} - mi := &file_vtctldata_proto_msgTypes[166] + mi := &file_vtctldata_proto_msgTypes[172] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10460,7 +10816,7 @@ func (x *RefreshStateByShardResponse) String() string { func (*RefreshStateByShardResponse) ProtoMessage() {} func (x *RefreshStateByShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[166] + mi := &file_vtctldata_proto_msgTypes[172] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10473,7 +10829,7 @@ func (x *RefreshStateByShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateByShardResponse.ProtoReflect.Descriptor instead. func (*RefreshStateByShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{166} + return file_vtctldata_proto_rawDescGZIP(), []int{172} } func (x *RefreshStateByShardResponse) GetIsPartialRefresh() bool { @@ -10500,7 +10856,7 @@ type ReloadSchemaRequest struct { func (x *ReloadSchemaRequest) Reset() { *x = ReloadSchemaRequest{} - mi := &file_vtctldata_proto_msgTypes[167] + mi := &file_vtctldata_proto_msgTypes[173] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10512,7 +10868,7 @@ func (x *ReloadSchemaRequest) String() string { func (*ReloadSchemaRequest) ProtoMessage() {} func (x *ReloadSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[167] + mi := &file_vtctldata_proto_msgTypes[173] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10525,7 +10881,7 @@ func (x *ReloadSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaRequest.ProtoReflect.Descriptor instead. func (*ReloadSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{167} + return file_vtctldata_proto_rawDescGZIP(), []int{173} } func (x *ReloadSchemaRequest) GetTabletAlias() *topodata.TabletAlias { @@ -10543,7 +10899,7 @@ type ReloadSchemaResponse struct { func (x *ReloadSchemaResponse) Reset() { *x = ReloadSchemaResponse{} - mi := &file_vtctldata_proto_msgTypes[168] + mi := &file_vtctldata_proto_msgTypes[174] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10555,7 +10911,7 @@ func (x *ReloadSchemaResponse) String() string { func (*ReloadSchemaResponse) ProtoMessage() {} func (x *ReloadSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[168] + mi := &file_vtctldata_proto_msgTypes[174] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10568,7 +10924,7 @@ func (x *ReloadSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaResponse.ProtoReflect.Descriptor instead. func (*ReloadSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{168} + return file_vtctldata_proto_rawDescGZIP(), []int{174} } type ReloadSchemaKeyspaceRequest struct { @@ -10587,7 +10943,7 @@ type ReloadSchemaKeyspaceRequest struct { func (x *ReloadSchemaKeyspaceRequest) Reset() { *x = ReloadSchemaKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[169] + mi := &file_vtctldata_proto_msgTypes[175] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10599,7 +10955,7 @@ func (x *ReloadSchemaKeyspaceRequest) String() string { func (*ReloadSchemaKeyspaceRequest) ProtoMessage() {} func (x *ReloadSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[169] + mi := &file_vtctldata_proto_msgTypes[175] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10612,7 +10968,7 @@ func (x *ReloadSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ReloadSchemaKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{169} + return file_vtctldata_proto_rawDescGZIP(), []int{175} } func (x *ReloadSchemaKeyspaceRequest) GetKeyspace() string { @@ -10653,7 +11009,7 @@ type ReloadSchemaKeyspaceResponse struct { func (x *ReloadSchemaKeyspaceResponse) Reset() { *x = ReloadSchemaKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[170] + mi := &file_vtctldata_proto_msgTypes[176] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10665,7 +11021,7 @@ func (x *ReloadSchemaKeyspaceResponse) String() string { func (*ReloadSchemaKeyspaceResponse) ProtoMessage() {} func (x *ReloadSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[170] + mi := &file_vtctldata_proto_msgTypes[176] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10678,7 +11034,7 @@ func (x *ReloadSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ReloadSchemaKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{170} + return file_vtctldata_proto_rawDescGZIP(), []int{176} } func (x *ReloadSchemaKeyspaceResponse) GetEvents() []*logutil.Event { @@ -10703,7 +11059,7 @@ type ReloadSchemaShardRequest struct { func (x *ReloadSchemaShardRequest) Reset() { *x = ReloadSchemaShardRequest{} - mi := &file_vtctldata_proto_msgTypes[171] + mi := &file_vtctldata_proto_msgTypes[177] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10715,7 +11071,7 @@ func (x *ReloadSchemaShardRequest) String() string { func (*ReloadSchemaShardRequest) ProtoMessage() {} func (x *ReloadSchemaShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[171] + mi := &file_vtctldata_proto_msgTypes[177] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10728,7 +11084,7 @@ func (x *ReloadSchemaShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaShardRequest.ProtoReflect.Descriptor instead. func (*ReloadSchemaShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{171} + return file_vtctldata_proto_rawDescGZIP(), []int{177} } func (x *ReloadSchemaShardRequest) GetKeyspace() string { @@ -10776,7 +11132,7 @@ type ReloadSchemaShardResponse struct { func (x *ReloadSchemaShardResponse) Reset() { *x = ReloadSchemaShardResponse{} - mi := &file_vtctldata_proto_msgTypes[172] + mi := &file_vtctldata_proto_msgTypes[178] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10788,7 +11144,7 @@ func (x *ReloadSchemaShardResponse) String() string { func (*ReloadSchemaShardResponse) ProtoMessage() {} func (x *ReloadSchemaShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[172] + mi := &file_vtctldata_proto_msgTypes[178] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10801,7 +11157,7 @@ func (x *ReloadSchemaShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaShardResponse.ProtoReflect.Descriptor instead. func (*ReloadSchemaShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{172} + return file_vtctldata_proto_rawDescGZIP(), []int{178} } func (x *ReloadSchemaShardResponse) GetEvents() []*logutil.Event { @@ -10823,7 +11179,7 @@ type RemoveBackupRequest struct { func (x *RemoveBackupRequest) Reset() { *x = RemoveBackupRequest{} - mi := &file_vtctldata_proto_msgTypes[173] + mi := &file_vtctldata_proto_msgTypes[179] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10835,7 +11191,7 @@ func (x *RemoveBackupRequest) String() string { func (*RemoveBackupRequest) ProtoMessage() {} func (x *RemoveBackupRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[173] + mi := &file_vtctldata_proto_msgTypes[179] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10848,7 +11204,7 @@ func (x *RemoveBackupRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveBackupRequest.ProtoReflect.Descriptor instead. func (*RemoveBackupRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{173} + return file_vtctldata_proto_rawDescGZIP(), []int{179} } func (x *RemoveBackupRequest) GetKeyspace() string { @@ -10880,7 +11236,7 @@ type RemoveBackupResponse struct { func (x *RemoveBackupResponse) Reset() { *x = RemoveBackupResponse{} - mi := &file_vtctldata_proto_msgTypes[174] + mi := &file_vtctldata_proto_msgTypes[180] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10892,7 +11248,7 @@ func (x *RemoveBackupResponse) String() string { func (*RemoveBackupResponse) ProtoMessage() {} func (x *RemoveBackupResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[174] + mi := &file_vtctldata_proto_msgTypes[180] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10905,7 +11261,7 @@ func (x *RemoveBackupResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveBackupResponse.ProtoReflect.Descriptor instead. func (*RemoveBackupResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{174} + return file_vtctldata_proto_rawDescGZIP(), []int{180} } type RemoveKeyspaceCellRequest struct { @@ -10926,7 +11282,7 @@ type RemoveKeyspaceCellRequest struct { func (x *RemoveKeyspaceCellRequest) Reset() { *x = RemoveKeyspaceCellRequest{} - mi := &file_vtctldata_proto_msgTypes[175] + mi := &file_vtctldata_proto_msgTypes[181] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10938,7 +11294,7 @@ func (x *RemoveKeyspaceCellRequest) String() string { func (*RemoveKeyspaceCellRequest) ProtoMessage() {} func (x *RemoveKeyspaceCellRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[175] + mi := &file_vtctldata_proto_msgTypes[181] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10951,7 +11307,7 @@ func (x *RemoveKeyspaceCellRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveKeyspaceCellRequest.ProtoReflect.Descriptor instead. func (*RemoveKeyspaceCellRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{175} + return file_vtctldata_proto_rawDescGZIP(), []int{181} } func (x *RemoveKeyspaceCellRequest) GetKeyspace() string { @@ -10990,7 +11346,7 @@ type RemoveKeyspaceCellResponse struct { func (x *RemoveKeyspaceCellResponse) Reset() { *x = RemoveKeyspaceCellResponse{} - mi := &file_vtctldata_proto_msgTypes[176] + mi := &file_vtctldata_proto_msgTypes[182] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11002,7 +11358,7 @@ func (x *RemoveKeyspaceCellResponse) String() string { func (*RemoveKeyspaceCellResponse) ProtoMessage() {} func (x *RemoveKeyspaceCellResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[176] + mi := &file_vtctldata_proto_msgTypes[182] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11015,7 +11371,7 @@ func (x *RemoveKeyspaceCellResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveKeyspaceCellResponse.ProtoReflect.Descriptor instead. func (*RemoveKeyspaceCellResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{176} + return file_vtctldata_proto_rawDescGZIP(), []int{182} } type RemoveShardCellRequest struct { @@ -11037,7 +11393,7 @@ type RemoveShardCellRequest struct { func (x *RemoveShardCellRequest) Reset() { *x = RemoveShardCellRequest{} - mi := &file_vtctldata_proto_msgTypes[177] + mi := &file_vtctldata_proto_msgTypes[183] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11049,7 +11405,7 @@ func (x *RemoveShardCellRequest) String() string { func (*RemoveShardCellRequest) ProtoMessage() {} func (x *RemoveShardCellRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[177] + mi := &file_vtctldata_proto_msgTypes[183] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11062,7 +11418,7 @@ func (x *RemoveShardCellRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveShardCellRequest.ProtoReflect.Descriptor instead. func (*RemoveShardCellRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{177} + return file_vtctldata_proto_rawDescGZIP(), []int{183} } func (x *RemoveShardCellRequest) GetKeyspace() string { @@ -11108,7 +11464,7 @@ type RemoveShardCellResponse struct { func (x *RemoveShardCellResponse) Reset() { *x = RemoveShardCellResponse{} - mi := &file_vtctldata_proto_msgTypes[178] + mi := &file_vtctldata_proto_msgTypes[184] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11120,7 +11476,7 @@ func (x *RemoveShardCellResponse) String() string { func (*RemoveShardCellResponse) ProtoMessage() {} func (x *RemoveShardCellResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[178] + mi := &file_vtctldata_proto_msgTypes[184] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11133,7 +11489,7 @@ func (x *RemoveShardCellResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveShardCellResponse.ProtoReflect.Descriptor instead. func (*RemoveShardCellResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{178} + return file_vtctldata_proto_rawDescGZIP(), []int{184} } type ReparentTabletRequest struct { @@ -11148,7 +11504,7 @@ type ReparentTabletRequest struct { func (x *ReparentTabletRequest) Reset() { *x = ReparentTabletRequest{} - mi := &file_vtctldata_proto_msgTypes[179] + mi := &file_vtctldata_proto_msgTypes[185] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11160,7 +11516,7 @@ func (x *ReparentTabletRequest) String() string { func (*ReparentTabletRequest) ProtoMessage() {} func (x *ReparentTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[179] + mi := &file_vtctldata_proto_msgTypes[185] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11173,7 +11529,7 @@ func (x *ReparentTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReparentTabletRequest.ProtoReflect.Descriptor instead. func (*ReparentTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{179} + return file_vtctldata_proto_rawDescGZIP(), []int{185} } func (x *ReparentTabletRequest) GetTablet() *topodata.TabletAlias { @@ -11198,7 +11554,7 @@ type ReparentTabletResponse struct { func (x *ReparentTabletResponse) Reset() { *x = ReparentTabletResponse{} - mi := &file_vtctldata_proto_msgTypes[180] + mi := &file_vtctldata_proto_msgTypes[186] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11210,7 +11566,7 @@ func (x *ReparentTabletResponse) String() string { func (*ReparentTabletResponse) ProtoMessage() {} func (x *ReparentTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[180] + mi := &file_vtctldata_proto_msgTypes[186] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11223,7 +11579,7 @@ func (x *ReparentTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReparentTabletResponse.ProtoReflect.Descriptor instead. func (*ReparentTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{180} + return file_vtctldata_proto_rawDescGZIP(), []int{186} } func (x *ReparentTabletResponse) GetKeyspace() string { @@ -11275,7 +11631,7 @@ type ReshardCreateRequest struct { func (x *ReshardCreateRequest) Reset() { *x = ReshardCreateRequest{} - mi := &file_vtctldata_proto_msgTypes[181] + mi := &file_vtctldata_proto_msgTypes[187] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11287,7 +11643,7 @@ func (x *ReshardCreateRequest) String() string { func (*ReshardCreateRequest) ProtoMessage() {} func (x *ReshardCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[181] + mi := &file_vtctldata_proto_msgTypes[187] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11300,7 +11656,7 @@ func (x *ReshardCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReshardCreateRequest.ProtoReflect.Descriptor instead. func (*ReshardCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{181} + return file_vtctldata_proto_rawDescGZIP(), []int{187} } func (x *ReshardCreateRequest) GetWorkflow() string { @@ -11418,7 +11774,7 @@ type RestoreFromBackupRequest struct { func (x *RestoreFromBackupRequest) Reset() { *x = RestoreFromBackupRequest{} - mi := &file_vtctldata_proto_msgTypes[182] + mi := &file_vtctldata_proto_msgTypes[188] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11430,7 +11786,7 @@ func (x *RestoreFromBackupRequest) String() string { func (*RestoreFromBackupRequest) ProtoMessage() {} func (x *RestoreFromBackupRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[182] + mi := &file_vtctldata_proto_msgTypes[188] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11443,7 +11799,7 @@ func (x *RestoreFromBackupRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreFromBackupRequest.ProtoReflect.Descriptor instead. func (*RestoreFromBackupRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{182} + return file_vtctldata_proto_rawDescGZIP(), []int{188} } func (x *RestoreFromBackupRequest) GetTabletAlias() *topodata.TabletAlias { @@ -11502,7 +11858,7 @@ type RestoreFromBackupResponse struct { func (x *RestoreFromBackupResponse) Reset() { *x = RestoreFromBackupResponse{} - mi := &file_vtctldata_proto_msgTypes[183] + mi := &file_vtctldata_proto_msgTypes[189] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11514,7 +11870,7 @@ func (x *RestoreFromBackupResponse) String() string { func (*RestoreFromBackupResponse) ProtoMessage() {} func (x *RestoreFromBackupResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[183] + mi := &file_vtctldata_proto_msgTypes[189] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11527,7 +11883,7 @@ func (x *RestoreFromBackupResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreFromBackupResponse.ProtoReflect.Descriptor instead. func (*RestoreFromBackupResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{183} + return file_vtctldata_proto_rawDescGZIP(), []int{189} } func (x *RestoreFromBackupResponse) GetTabletAlias() *topodata.TabletAlias { @@ -11569,7 +11925,7 @@ type RetrySchemaMigrationRequest struct { func (x *RetrySchemaMigrationRequest) Reset() { *x = RetrySchemaMigrationRequest{} - mi := &file_vtctldata_proto_msgTypes[184] + mi := &file_vtctldata_proto_msgTypes[190] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11581,7 +11937,7 @@ func (x *RetrySchemaMigrationRequest) String() string { func (*RetrySchemaMigrationRequest) ProtoMessage() {} func (x *RetrySchemaMigrationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[184] + mi := &file_vtctldata_proto_msgTypes[190] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11594,7 +11950,7 @@ func (x *RetrySchemaMigrationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RetrySchemaMigrationRequest.ProtoReflect.Descriptor instead. func (*RetrySchemaMigrationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{184} + return file_vtctldata_proto_rawDescGZIP(), []int{190} } func (x *RetrySchemaMigrationRequest) GetKeyspace() string { @@ -11621,7 +11977,7 @@ type RetrySchemaMigrationResponse struct { func (x *RetrySchemaMigrationResponse) Reset() { *x = RetrySchemaMigrationResponse{} - mi := &file_vtctldata_proto_msgTypes[185] + mi := &file_vtctldata_proto_msgTypes[191] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11633,7 +11989,7 @@ func (x *RetrySchemaMigrationResponse) String() string { func (*RetrySchemaMigrationResponse) ProtoMessage() {} func (x *RetrySchemaMigrationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[185] + mi := &file_vtctldata_proto_msgTypes[191] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11646,7 +12002,7 @@ func (x *RetrySchemaMigrationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RetrySchemaMigrationResponse.ProtoReflect.Descriptor instead. func (*RetrySchemaMigrationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{185} + return file_vtctldata_proto_rawDescGZIP(), []int{191} } func (x *RetrySchemaMigrationResponse) GetRowsAffectedByShard() map[string]uint64 { @@ -11666,7 +12022,7 @@ type RunHealthCheckRequest struct { func (x *RunHealthCheckRequest) Reset() { *x = RunHealthCheckRequest{} - mi := &file_vtctldata_proto_msgTypes[186] + mi := &file_vtctldata_proto_msgTypes[192] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11678,7 +12034,7 @@ func (x *RunHealthCheckRequest) String() string { func (*RunHealthCheckRequest) ProtoMessage() {} func (x *RunHealthCheckRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[186] + mi := &file_vtctldata_proto_msgTypes[192] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11691,7 +12047,7 @@ func (x *RunHealthCheckRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunHealthCheckRequest.ProtoReflect.Descriptor instead. func (*RunHealthCheckRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{186} + return file_vtctldata_proto_rawDescGZIP(), []int{192} } func (x *RunHealthCheckRequest) GetTabletAlias() *topodata.TabletAlias { @@ -11709,7 +12065,7 @@ type RunHealthCheckResponse struct { func (x *RunHealthCheckResponse) Reset() { *x = RunHealthCheckResponse{} - mi := &file_vtctldata_proto_msgTypes[187] + mi := &file_vtctldata_proto_msgTypes[193] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11721,7 +12077,7 @@ func (x *RunHealthCheckResponse) String() string { func (*RunHealthCheckResponse) ProtoMessage() {} func (x *RunHealthCheckResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[187] + mi := &file_vtctldata_proto_msgTypes[193] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11734,7 +12090,7 @@ func (x *RunHealthCheckResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RunHealthCheckResponse.ProtoReflect.Descriptor instead. func (*RunHealthCheckResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{187} + return file_vtctldata_proto_rawDescGZIP(), []int{193} } type SetKeyspaceDurabilityPolicyRequest struct { @@ -11748,7 +12104,7 @@ type SetKeyspaceDurabilityPolicyRequest struct { func (x *SetKeyspaceDurabilityPolicyRequest) Reset() { *x = SetKeyspaceDurabilityPolicyRequest{} - mi := &file_vtctldata_proto_msgTypes[188] + mi := &file_vtctldata_proto_msgTypes[194] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11760,7 +12116,7 @@ func (x *SetKeyspaceDurabilityPolicyRequest) String() string { func (*SetKeyspaceDurabilityPolicyRequest) ProtoMessage() {} func (x *SetKeyspaceDurabilityPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[188] + mi := &file_vtctldata_proto_msgTypes[194] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11773,7 +12129,7 @@ func (x *SetKeyspaceDurabilityPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use SetKeyspaceDurabilityPolicyRequest.ProtoReflect.Descriptor instead. func (*SetKeyspaceDurabilityPolicyRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{188} + return file_vtctldata_proto_rawDescGZIP(), []int{194} } func (x *SetKeyspaceDurabilityPolicyRequest) GetKeyspace() string { @@ -11801,7 +12157,7 @@ type SetKeyspaceDurabilityPolicyResponse struct { func (x *SetKeyspaceDurabilityPolicyResponse) Reset() { *x = SetKeyspaceDurabilityPolicyResponse{} - mi := &file_vtctldata_proto_msgTypes[189] + mi := &file_vtctldata_proto_msgTypes[195] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11813,7 +12169,7 @@ func (x *SetKeyspaceDurabilityPolicyResponse) String() string { func (*SetKeyspaceDurabilityPolicyResponse) ProtoMessage() {} func (x *SetKeyspaceDurabilityPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[189] + mi := &file_vtctldata_proto_msgTypes[195] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11826,7 +12182,7 @@ func (x *SetKeyspaceDurabilityPolicyResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use SetKeyspaceDurabilityPolicyResponse.ProtoReflect.Descriptor instead. func (*SetKeyspaceDurabilityPolicyResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{189} + return file_vtctldata_proto_rawDescGZIP(), []int{195} } func (x *SetKeyspaceDurabilityPolicyResponse) GetKeyspace() *topodata.Keyspace { @@ -11847,7 +12203,7 @@ type SetKeyspaceShardingInfoRequest struct { func (x *SetKeyspaceShardingInfoRequest) Reset() { *x = SetKeyspaceShardingInfoRequest{} - mi := &file_vtctldata_proto_msgTypes[190] + mi := &file_vtctldata_proto_msgTypes[196] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11859,7 +12215,7 @@ func (x *SetKeyspaceShardingInfoRequest) String() string { func (*SetKeyspaceShardingInfoRequest) ProtoMessage() {} func (x *SetKeyspaceShardingInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[190] + mi := &file_vtctldata_proto_msgTypes[196] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11872,7 +12228,7 @@ func (x *SetKeyspaceShardingInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetKeyspaceShardingInfoRequest.ProtoReflect.Descriptor instead. func (*SetKeyspaceShardingInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{190} + return file_vtctldata_proto_rawDescGZIP(), []int{196} } func (x *SetKeyspaceShardingInfoRequest) GetKeyspace() string { @@ -11900,7 +12256,7 @@ type SetKeyspaceShardingInfoResponse struct { func (x *SetKeyspaceShardingInfoResponse) Reset() { *x = SetKeyspaceShardingInfoResponse{} - mi := &file_vtctldata_proto_msgTypes[191] + mi := &file_vtctldata_proto_msgTypes[197] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11912,7 +12268,7 @@ func (x *SetKeyspaceShardingInfoResponse) String() string { func (*SetKeyspaceShardingInfoResponse) ProtoMessage() {} func (x *SetKeyspaceShardingInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[191] + mi := &file_vtctldata_proto_msgTypes[197] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11925,7 +12281,7 @@ func (x *SetKeyspaceShardingInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetKeyspaceShardingInfoResponse.ProtoReflect.Descriptor instead. func (*SetKeyspaceShardingInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{191} + return file_vtctldata_proto_rawDescGZIP(), []int{197} } func (x *SetKeyspaceShardingInfoResponse) GetKeyspace() *topodata.Keyspace { @@ -11947,7 +12303,7 @@ type SetShardIsPrimaryServingRequest struct { func (x *SetShardIsPrimaryServingRequest) Reset() { *x = SetShardIsPrimaryServingRequest{} - mi := &file_vtctldata_proto_msgTypes[192] + mi := &file_vtctldata_proto_msgTypes[198] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11959,7 +12315,7 @@ func (x *SetShardIsPrimaryServingRequest) String() string { func (*SetShardIsPrimaryServingRequest) ProtoMessage() {} func (x *SetShardIsPrimaryServingRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[192] + mi := &file_vtctldata_proto_msgTypes[198] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11972,7 +12328,7 @@ func (x *SetShardIsPrimaryServingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardIsPrimaryServingRequest.ProtoReflect.Descriptor instead. func (*SetShardIsPrimaryServingRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{192} + return file_vtctldata_proto_rawDescGZIP(), []int{198} } func (x *SetShardIsPrimaryServingRequest) GetKeyspace() string { @@ -12007,7 +12363,7 @@ type SetShardIsPrimaryServingResponse struct { func (x *SetShardIsPrimaryServingResponse) Reset() { *x = SetShardIsPrimaryServingResponse{} - mi := &file_vtctldata_proto_msgTypes[193] + mi := &file_vtctldata_proto_msgTypes[199] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12019,7 +12375,7 @@ func (x *SetShardIsPrimaryServingResponse) String() string { func (*SetShardIsPrimaryServingResponse) ProtoMessage() {} func (x *SetShardIsPrimaryServingResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[193] + mi := &file_vtctldata_proto_msgTypes[199] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12032,7 +12388,7 @@ func (x *SetShardIsPrimaryServingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardIsPrimaryServingResponse.ProtoReflect.Descriptor instead. func (*SetShardIsPrimaryServingResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{193} + return file_vtctldata_proto_rawDescGZIP(), []int{199} } func (x *SetShardIsPrimaryServingResponse) GetShard() *topodata.Shard { @@ -12072,7 +12428,7 @@ type SetShardTabletControlRequest struct { func (x *SetShardTabletControlRequest) Reset() { *x = SetShardTabletControlRequest{} - mi := &file_vtctldata_proto_msgTypes[194] + mi := &file_vtctldata_proto_msgTypes[200] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12084,7 +12440,7 @@ func (x *SetShardTabletControlRequest) String() string { func (*SetShardTabletControlRequest) ProtoMessage() {} func (x *SetShardTabletControlRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[194] + mi := &file_vtctldata_proto_msgTypes[200] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12097,7 +12453,7 @@ func (x *SetShardTabletControlRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardTabletControlRequest.ProtoReflect.Descriptor instead. func (*SetShardTabletControlRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{194} + return file_vtctldata_proto_rawDescGZIP(), []int{200} } func (x *SetShardTabletControlRequest) GetKeyspace() string { @@ -12160,7 +12516,7 @@ type SetShardTabletControlResponse struct { func (x *SetShardTabletControlResponse) Reset() { *x = SetShardTabletControlResponse{} - mi := &file_vtctldata_proto_msgTypes[195] + mi := &file_vtctldata_proto_msgTypes[201] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12172,7 +12528,7 @@ func (x *SetShardTabletControlResponse) String() string { func (*SetShardTabletControlResponse) ProtoMessage() {} func (x *SetShardTabletControlResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[195] + mi := &file_vtctldata_proto_msgTypes[201] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12185,7 +12541,7 @@ func (x *SetShardTabletControlResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardTabletControlResponse.ProtoReflect.Descriptor instead. func (*SetShardTabletControlResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{195} + return file_vtctldata_proto_rawDescGZIP(), []int{201} } func (x *SetShardTabletControlResponse) GetShard() *topodata.Shard { @@ -12206,7 +12562,7 @@ type SetWritableRequest struct { func (x *SetWritableRequest) Reset() { *x = SetWritableRequest{} - mi := &file_vtctldata_proto_msgTypes[196] + mi := &file_vtctldata_proto_msgTypes[202] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12218,7 +12574,7 @@ func (x *SetWritableRequest) String() string { func (*SetWritableRequest) ProtoMessage() {} func (x *SetWritableRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[196] + mi := &file_vtctldata_proto_msgTypes[202] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12231,7 +12587,7 @@ func (x *SetWritableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWritableRequest.ProtoReflect.Descriptor instead. func (*SetWritableRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{196} + return file_vtctldata_proto_rawDescGZIP(), []int{202} } func (x *SetWritableRequest) GetTabletAlias() *topodata.TabletAlias { @@ -12256,7 +12612,7 @@ type SetWritableResponse struct { func (x *SetWritableResponse) Reset() { *x = SetWritableResponse{} - mi := &file_vtctldata_proto_msgTypes[197] + mi := &file_vtctldata_proto_msgTypes[203] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12268,7 +12624,7 @@ func (x *SetWritableResponse) String() string { func (*SetWritableResponse) ProtoMessage() {} func (x *SetWritableResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[197] + mi := &file_vtctldata_proto_msgTypes[203] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12281,7 +12637,7 @@ func (x *SetWritableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWritableResponse.ProtoReflect.Descriptor instead. func (*SetWritableResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{197} + return file_vtctldata_proto_rawDescGZIP(), []int{203} } type ShardReplicationAddRequest struct { @@ -12296,7 +12652,7 @@ type ShardReplicationAddRequest struct { func (x *ShardReplicationAddRequest) Reset() { *x = ShardReplicationAddRequest{} - mi := &file_vtctldata_proto_msgTypes[198] + mi := &file_vtctldata_proto_msgTypes[204] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12308,7 +12664,7 @@ func (x *ShardReplicationAddRequest) String() string { func (*ShardReplicationAddRequest) ProtoMessage() {} func (x *ShardReplicationAddRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[198] + mi := &file_vtctldata_proto_msgTypes[204] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12321,7 +12677,7 @@ func (x *ShardReplicationAddRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationAddRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationAddRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{198} + return file_vtctldata_proto_rawDescGZIP(), []int{204} } func (x *ShardReplicationAddRequest) GetKeyspace() string { @@ -12353,7 +12709,7 @@ type ShardReplicationAddResponse struct { func (x *ShardReplicationAddResponse) Reset() { *x = ShardReplicationAddResponse{} - mi := &file_vtctldata_proto_msgTypes[199] + mi := &file_vtctldata_proto_msgTypes[205] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12365,7 +12721,7 @@ func (x *ShardReplicationAddResponse) String() string { func (*ShardReplicationAddResponse) ProtoMessage() {} func (x *ShardReplicationAddResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[199] + mi := &file_vtctldata_proto_msgTypes[205] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12378,7 +12734,7 @@ func (x *ShardReplicationAddResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationAddResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationAddResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{199} + return file_vtctldata_proto_rawDescGZIP(), []int{205} } type ShardReplicationFixRequest struct { @@ -12393,7 +12749,7 @@ type ShardReplicationFixRequest struct { func (x *ShardReplicationFixRequest) Reset() { *x = ShardReplicationFixRequest{} - mi := &file_vtctldata_proto_msgTypes[200] + mi := &file_vtctldata_proto_msgTypes[206] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12405,7 +12761,7 @@ func (x *ShardReplicationFixRequest) String() string { func (*ShardReplicationFixRequest) ProtoMessage() {} func (x *ShardReplicationFixRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[200] + mi := &file_vtctldata_proto_msgTypes[206] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12418,7 +12774,7 @@ func (x *ShardReplicationFixRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationFixRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationFixRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{200} + return file_vtctldata_proto_rawDescGZIP(), []int{206} } func (x *ShardReplicationFixRequest) GetKeyspace() string { @@ -12455,7 +12811,7 @@ type ShardReplicationFixResponse struct { func (x *ShardReplicationFixResponse) Reset() { *x = ShardReplicationFixResponse{} - mi := &file_vtctldata_proto_msgTypes[201] + mi := &file_vtctldata_proto_msgTypes[207] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12467,7 +12823,7 @@ func (x *ShardReplicationFixResponse) String() string { func (*ShardReplicationFixResponse) ProtoMessage() {} func (x *ShardReplicationFixResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[201] + mi := &file_vtctldata_proto_msgTypes[207] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12480,7 +12836,7 @@ func (x *ShardReplicationFixResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationFixResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationFixResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{201} + return file_vtctldata_proto_rawDescGZIP(), []int{207} } func (x *ShardReplicationFixResponse) GetError() *topodata.ShardReplicationError { @@ -12501,7 +12857,7 @@ type ShardReplicationPositionsRequest struct { func (x *ShardReplicationPositionsRequest) Reset() { *x = ShardReplicationPositionsRequest{} - mi := &file_vtctldata_proto_msgTypes[202] + mi := &file_vtctldata_proto_msgTypes[208] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12513,7 +12869,7 @@ func (x *ShardReplicationPositionsRequest) String() string { func (*ShardReplicationPositionsRequest) ProtoMessage() {} func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[202] + mi := &file_vtctldata_proto_msgTypes[208] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12526,7 +12882,7 @@ func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationPositionsRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{202} + return file_vtctldata_proto_rawDescGZIP(), []int{208} } func (x *ShardReplicationPositionsRequest) GetKeyspace() string { @@ -12558,7 +12914,7 @@ type ShardReplicationPositionsResponse struct { func (x *ShardReplicationPositionsResponse) Reset() { *x = ShardReplicationPositionsResponse{} - mi := &file_vtctldata_proto_msgTypes[203] + mi := &file_vtctldata_proto_msgTypes[209] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12570,7 +12926,7 @@ func (x *ShardReplicationPositionsResponse) String() string { func (*ShardReplicationPositionsResponse) ProtoMessage() {} func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[203] + mi := &file_vtctldata_proto_msgTypes[209] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12583,7 +12939,7 @@ func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ShardReplicationPositionsResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{203} + return file_vtctldata_proto_rawDescGZIP(), []int{209} } func (x *ShardReplicationPositionsResponse) GetReplicationStatuses() map[string]*replicationdata.Status { @@ -12612,7 +12968,7 @@ type ShardReplicationRemoveRequest struct { func (x *ShardReplicationRemoveRequest) Reset() { *x = ShardReplicationRemoveRequest{} - mi := &file_vtctldata_proto_msgTypes[204] + mi := &file_vtctldata_proto_msgTypes[210] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12624,7 +12980,7 @@ func (x *ShardReplicationRemoveRequest) String() string { func (*ShardReplicationRemoveRequest) ProtoMessage() {} func (x *ShardReplicationRemoveRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[204] + mi := &file_vtctldata_proto_msgTypes[210] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12637,7 +12993,7 @@ func (x *ShardReplicationRemoveRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationRemoveRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationRemoveRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{204} + return file_vtctldata_proto_rawDescGZIP(), []int{210} } func (x *ShardReplicationRemoveRequest) GetKeyspace() string { @@ -12669,7 +13025,7 @@ type ShardReplicationRemoveResponse struct { func (x *ShardReplicationRemoveResponse) Reset() { *x = ShardReplicationRemoveResponse{} - mi := &file_vtctldata_proto_msgTypes[205] + mi := &file_vtctldata_proto_msgTypes[211] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12681,7 +13037,7 @@ func (x *ShardReplicationRemoveResponse) String() string { func (*ShardReplicationRemoveResponse) ProtoMessage() {} func (x *ShardReplicationRemoveResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[205] + mi := &file_vtctldata_proto_msgTypes[211] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12694,7 +13050,7 @@ func (x *ShardReplicationRemoveResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationRemoveResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationRemoveResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{205} + return file_vtctldata_proto_rawDescGZIP(), []int{211} } type SleepTabletRequest struct { @@ -12708,7 +13064,7 @@ type SleepTabletRequest struct { func (x *SleepTabletRequest) Reset() { *x = SleepTabletRequest{} - mi := &file_vtctldata_proto_msgTypes[206] + mi := &file_vtctldata_proto_msgTypes[212] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12720,7 +13076,7 @@ func (x *SleepTabletRequest) String() string { func (*SleepTabletRequest) ProtoMessage() {} func (x *SleepTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[206] + mi := &file_vtctldata_proto_msgTypes[212] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12733,7 +13089,7 @@ func (x *SleepTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SleepTabletRequest.ProtoReflect.Descriptor instead. func (*SleepTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{206} + return file_vtctldata_proto_rawDescGZIP(), []int{212} } func (x *SleepTabletRequest) GetTabletAlias() *topodata.TabletAlias { @@ -12758,7 +13114,7 @@ type SleepTabletResponse struct { func (x *SleepTabletResponse) Reset() { *x = SleepTabletResponse{} - mi := &file_vtctldata_proto_msgTypes[207] + mi := &file_vtctldata_proto_msgTypes[213] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12770,7 +13126,7 @@ func (x *SleepTabletResponse) String() string { func (*SleepTabletResponse) ProtoMessage() {} func (x *SleepTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[207] + mi := &file_vtctldata_proto_msgTypes[213] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12783,7 +13139,7 @@ func (x *SleepTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SleepTabletResponse.ProtoReflect.Descriptor instead. func (*SleepTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{207} + return file_vtctldata_proto_rawDescGZIP(), []int{213} } type SourceShardAddRequest struct { @@ -12806,7 +13162,7 @@ type SourceShardAddRequest struct { func (x *SourceShardAddRequest) Reset() { *x = SourceShardAddRequest{} - mi := &file_vtctldata_proto_msgTypes[208] + mi := &file_vtctldata_proto_msgTypes[214] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12818,7 +13174,7 @@ func (x *SourceShardAddRequest) String() string { func (*SourceShardAddRequest) ProtoMessage() {} func (x *SourceShardAddRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[208] + mi := &file_vtctldata_proto_msgTypes[214] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12831,7 +13187,7 @@ func (x *SourceShardAddRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardAddRequest.ProtoReflect.Descriptor instead. func (*SourceShardAddRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{208} + return file_vtctldata_proto_rawDescGZIP(), []int{214} } func (x *SourceShardAddRequest) GetKeyspace() string { @@ -12894,7 +13250,7 @@ type SourceShardAddResponse struct { func (x *SourceShardAddResponse) Reset() { *x = SourceShardAddResponse{} - mi := &file_vtctldata_proto_msgTypes[209] + mi := &file_vtctldata_proto_msgTypes[215] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12906,7 +13262,7 @@ func (x *SourceShardAddResponse) String() string { func (*SourceShardAddResponse) ProtoMessage() {} func (x *SourceShardAddResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[209] + mi := &file_vtctldata_proto_msgTypes[215] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12919,7 +13275,7 @@ func (x *SourceShardAddResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardAddResponse.ProtoReflect.Descriptor instead. func (*SourceShardAddResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{209} + return file_vtctldata_proto_rawDescGZIP(), []int{215} } func (x *SourceShardAddResponse) GetShard() *topodata.Shard { @@ -12941,7 +13297,7 @@ type SourceShardDeleteRequest struct { func (x *SourceShardDeleteRequest) Reset() { *x = SourceShardDeleteRequest{} - mi := &file_vtctldata_proto_msgTypes[210] + mi := &file_vtctldata_proto_msgTypes[216] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12953,7 +13309,7 @@ func (x *SourceShardDeleteRequest) String() string { func (*SourceShardDeleteRequest) ProtoMessage() {} func (x *SourceShardDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[210] + mi := &file_vtctldata_proto_msgTypes[216] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12966,7 +13322,7 @@ func (x *SourceShardDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardDeleteRequest.ProtoReflect.Descriptor instead. func (*SourceShardDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{210} + return file_vtctldata_proto_rawDescGZIP(), []int{216} } func (x *SourceShardDeleteRequest) GetKeyspace() string { @@ -13001,7 +13357,7 @@ type SourceShardDeleteResponse struct { func (x *SourceShardDeleteResponse) Reset() { *x = SourceShardDeleteResponse{} - mi := &file_vtctldata_proto_msgTypes[211] + mi := &file_vtctldata_proto_msgTypes[217] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13013,7 +13369,7 @@ func (x *SourceShardDeleteResponse) String() string { func (*SourceShardDeleteResponse) ProtoMessage() {} func (x *SourceShardDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[211] + mi := &file_vtctldata_proto_msgTypes[217] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13026,7 +13382,7 @@ func (x *SourceShardDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardDeleteResponse.ProtoReflect.Descriptor instead. func (*SourceShardDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{211} + return file_vtctldata_proto_rawDescGZIP(), []int{217} } func (x *SourceShardDeleteResponse) GetShard() *topodata.Shard { @@ -13046,7 +13402,7 @@ type StartReplicationRequest struct { func (x *StartReplicationRequest) Reset() { *x = StartReplicationRequest{} - mi := &file_vtctldata_proto_msgTypes[212] + mi := &file_vtctldata_proto_msgTypes[218] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13058,7 +13414,7 @@ func (x *StartReplicationRequest) String() string { func (*StartReplicationRequest) ProtoMessage() {} func (x *StartReplicationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[212] + mi := &file_vtctldata_proto_msgTypes[218] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13071,7 +13427,7 @@ func (x *StartReplicationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartReplicationRequest.ProtoReflect.Descriptor instead. func (*StartReplicationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{212} + return file_vtctldata_proto_rawDescGZIP(), []int{218} } func (x *StartReplicationRequest) GetTabletAlias() *topodata.TabletAlias { @@ -13089,7 +13445,7 @@ type StartReplicationResponse struct { func (x *StartReplicationResponse) Reset() { *x = StartReplicationResponse{} - mi := &file_vtctldata_proto_msgTypes[213] + mi := &file_vtctldata_proto_msgTypes[219] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13101,7 +13457,7 @@ func (x *StartReplicationResponse) String() string { func (*StartReplicationResponse) ProtoMessage() {} func (x *StartReplicationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[213] + mi := &file_vtctldata_proto_msgTypes[219] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13114,7 +13470,7 @@ func (x *StartReplicationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StartReplicationResponse.ProtoReflect.Descriptor instead. func (*StartReplicationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{213} + return file_vtctldata_proto_rawDescGZIP(), []int{219} } type StopReplicationRequest struct { @@ -13127,7 +13483,7 @@ type StopReplicationRequest struct { func (x *StopReplicationRequest) Reset() { *x = StopReplicationRequest{} - mi := &file_vtctldata_proto_msgTypes[214] + mi := &file_vtctldata_proto_msgTypes[220] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13139,7 +13495,7 @@ func (x *StopReplicationRequest) String() string { func (*StopReplicationRequest) ProtoMessage() {} func (x *StopReplicationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[214] + mi := &file_vtctldata_proto_msgTypes[220] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13152,7 +13508,7 @@ func (x *StopReplicationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StopReplicationRequest.ProtoReflect.Descriptor instead. func (*StopReplicationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{214} + return file_vtctldata_proto_rawDescGZIP(), []int{220} } func (x *StopReplicationRequest) GetTabletAlias() *topodata.TabletAlias { @@ -13170,7 +13526,7 @@ type StopReplicationResponse struct { func (x *StopReplicationResponse) Reset() { *x = StopReplicationResponse{} - mi := &file_vtctldata_proto_msgTypes[215] + mi := &file_vtctldata_proto_msgTypes[221] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13182,7 +13538,7 @@ func (x *StopReplicationResponse) String() string { func (*StopReplicationResponse) ProtoMessage() {} func (x *StopReplicationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[215] + mi := &file_vtctldata_proto_msgTypes[221] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13195,7 +13551,7 @@ func (x *StopReplicationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StopReplicationResponse.ProtoReflect.Descriptor instead. func (*StopReplicationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{215} + return file_vtctldata_proto_rawDescGZIP(), []int{221} } type TabletExternallyReparentedRequest struct { @@ -13210,7 +13566,7 @@ type TabletExternallyReparentedRequest struct { func (x *TabletExternallyReparentedRequest) Reset() { *x = TabletExternallyReparentedRequest{} - mi := &file_vtctldata_proto_msgTypes[216] + mi := &file_vtctldata_proto_msgTypes[222] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13222,7 +13578,7 @@ func (x *TabletExternallyReparentedRequest) String() string { func (*TabletExternallyReparentedRequest) ProtoMessage() {} func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[216] + mi := &file_vtctldata_proto_msgTypes[222] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13235,7 +13591,7 @@ func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedRequest.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{216} + return file_vtctldata_proto_rawDescGZIP(), []int{222} } func (x *TabletExternallyReparentedRequest) GetTablet() *topodata.TabletAlias { @@ -13258,7 +13614,7 @@ type TabletExternallyReparentedResponse struct { func (x *TabletExternallyReparentedResponse) Reset() { *x = TabletExternallyReparentedResponse{} - mi := &file_vtctldata_proto_msgTypes[217] + mi := &file_vtctldata_proto_msgTypes[223] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13270,7 +13626,7 @@ func (x *TabletExternallyReparentedResponse) String() string { func (*TabletExternallyReparentedResponse) ProtoMessage() {} func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[217] + mi := &file_vtctldata_proto_msgTypes[223] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13283,7 +13639,7 @@ func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedResponse.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{217} + return file_vtctldata_proto_rawDescGZIP(), []int{223} } func (x *TabletExternallyReparentedResponse) GetKeyspace() string { @@ -13325,7 +13681,7 @@ type UpdateCellInfoRequest struct { func (x *UpdateCellInfoRequest) Reset() { *x = UpdateCellInfoRequest{} - mi := &file_vtctldata_proto_msgTypes[218] + mi := &file_vtctldata_proto_msgTypes[224] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13337,7 +13693,7 @@ func (x *UpdateCellInfoRequest) String() string { func (*UpdateCellInfoRequest) ProtoMessage() {} func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[218] + mi := &file_vtctldata_proto_msgTypes[224] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13350,7 +13706,7 @@ func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoRequest.ProtoReflect.Descriptor instead. func (*UpdateCellInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{218} + return file_vtctldata_proto_rawDescGZIP(), []int{224} } func (x *UpdateCellInfoRequest) GetName() string { @@ -13378,7 +13734,7 @@ type UpdateCellInfoResponse struct { func (x *UpdateCellInfoResponse) Reset() { *x = UpdateCellInfoResponse{} - mi := &file_vtctldata_proto_msgTypes[219] + mi := &file_vtctldata_proto_msgTypes[225] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13390,7 +13746,7 @@ func (x *UpdateCellInfoResponse) String() string { func (*UpdateCellInfoResponse) ProtoMessage() {} func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[219] + mi := &file_vtctldata_proto_msgTypes[225] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13403,7 +13759,7 @@ func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoResponse.ProtoReflect.Descriptor instead. func (*UpdateCellInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{219} + return file_vtctldata_proto_rawDescGZIP(), []int{225} } func (x *UpdateCellInfoResponse) GetName() string { @@ -13431,7 +13787,7 @@ type UpdateCellsAliasRequest struct { func (x *UpdateCellsAliasRequest) Reset() { *x = UpdateCellsAliasRequest{} - mi := &file_vtctldata_proto_msgTypes[220] + mi := &file_vtctldata_proto_msgTypes[226] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13443,7 +13799,7 @@ func (x *UpdateCellsAliasRequest) String() string { func (*UpdateCellsAliasRequest) ProtoMessage() {} func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[220] + mi := &file_vtctldata_proto_msgTypes[226] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13456,7 +13812,7 @@ func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasRequest.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{220} + return file_vtctldata_proto_rawDescGZIP(), []int{226} } func (x *UpdateCellsAliasRequest) GetName() string { @@ -13484,7 +13840,7 @@ type UpdateCellsAliasResponse struct { func (x *UpdateCellsAliasResponse) Reset() { *x = UpdateCellsAliasResponse{} - mi := &file_vtctldata_proto_msgTypes[221] + mi := &file_vtctldata_proto_msgTypes[227] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13496,7 +13852,7 @@ func (x *UpdateCellsAliasResponse) String() string { func (*UpdateCellsAliasResponse) ProtoMessage() {} func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[221] + mi := &file_vtctldata_proto_msgTypes[227] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13509,7 +13865,7 @@ func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasResponse.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{221} + return file_vtctldata_proto_rawDescGZIP(), []int{227} } func (x *UpdateCellsAliasResponse) GetName() string { @@ -13536,7 +13892,7 @@ type ValidateRequest struct { func (x *ValidateRequest) Reset() { *x = ValidateRequest{} - mi := &file_vtctldata_proto_msgTypes[222] + mi := &file_vtctldata_proto_msgTypes[228] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13548,7 +13904,7 @@ func (x *ValidateRequest) String() string { func (*ValidateRequest) ProtoMessage() {} func (x *ValidateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[222] + mi := &file_vtctldata_proto_msgTypes[228] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13561,7 +13917,7 @@ func (x *ValidateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRequest.ProtoReflect.Descriptor instead. func (*ValidateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{222} + return file_vtctldata_proto_rawDescGZIP(), []int{228} } func (x *ValidateRequest) GetPingTablets() bool { @@ -13582,7 +13938,7 @@ type ValidateResponse struct { func (x *ValidateResponse) Reset() { *x = ValidateResponse{} - mi := &file_vtctldata_proto_msgTypes[223] + mi := &file_vtctldata_proto_msgTypes[229] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13594,7 +13950,7 @@ func (x *ValidateResponse) String() string { func (*ValidateResponse) ProtoMessage() {} func (x *ValidateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[223] + mi := &file_vtctldata_proto_msgTypes[229] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13607,7 +13963,7 @@ func (x *ValidateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateResponse.ProtoReflect.Descriptor instead. func (*ValidateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{223} + return file_vtctldata_proto_rawDescGZIP(), []int{229} } func (x *ValidateResponse) GetResults() []string { @@ -13635,7 +13991,7 @@ type ValidateKeyspaceRequest struct { func (x *ValidateKeyspaceRequest) Reset() { *x = ValidateKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[224] + mi := &file_vtctldata_proto_msgTypes[230] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13647,7 +14003,7 @@ func (x *ValidateKeyspaceRequest) String() string { func (*ValidateKeyspaceRequest) ProtoMessage() {} func (x *ValidateKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[224] + mi := &file_vtctldata_proto_msgTypes[230] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13660,7 +14016,7 @@ func (x *ValidateKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{224} + return file_vtctldata_proto_rawDescGZIP(), []int{230} } func (x *ValidateKeyspaceRequest) GetKeyspace() string { @@ -13688,7 +14044,7 @@ type ValidateKeyspaceResponse struct { func (x *ValidateKeyspaceResponse) Reset() { *x = ValidateKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[225] + mi := &file_vtctldata_proto_msgTypes[231] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13700,7 +14056,7 @@ func (x *ValidateKeyspaceResponse) String() string { func (*ValidateKeyspaceResponse) ProtoMessage() {} func (x *ValidateKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[225] + mi := &file_vtctldata_proto_msgTypes[231] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13713,7 +14069,7 @@ func (x *ValidateKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{225} + return file_vtctldata_proto_rawDescGZIP(), []int{231} } func (x *ValidateKeyspaceResponse) GetResults() []string { @@ -13730,6 +14086,97 @@ func (x *ValidateKeyspaceResponse) GetResultsByShard() map[string]*ValidateShard return nil } +type ValidatePermissionsKeyspaceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // If you only want to validate a subset of the shards in the + // keyspace, then specify a list of shard names. + Shards []string `protobuf:"bytes,2,rep,name=shards,proto3" json:"shards,omitempty"` +} + +func (x *ValidatePermissionsKeyspaceRequest) Reset() { + *x = ValidatePermissionsKeyspaceRequest{} + mi := &file_vtctldata_proto_msgTypes[232] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ValidatePermissionsKeyspaceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatePermissionsKeyspaceRequest) ProtoMessage() {} + +func (x *ValidatePermissionsKeyspaceRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[232] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatePermissionsKeyspaceRequest.ProtoReflect.Descriptor instead. +func (*ValidatePermissionsKeyspaceRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{232} +} + +func (x *ValidatePermissionsKeyspaceRequest) GetKeyspace() string { + if x != nil { + return x.Keyspace + } + return "" +} + +func (x *ValidatePermissionsKeyspaceRequest) GetShards() []string { + if x != nil { + return x.Shards + } + return nil +} + +type ValidatePermissionsKeyspaceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ValidatePermissionsKeyspaceResponse) Reset() { + *x = ValidatePermissionsKeyspaceResponse{} + mi := &file_vtctldata_proto_msgTypes[233] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ValidatePermissionsKeyspaceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatePermissionsKeyspaceResponse) ProtoMessage() {} + +func (x *ValidatePermissionsKeyspaceResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[233] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatePermissionsKeyspaceResponse.ProtoReflect.Descriptor instead. +func (*ValidatePermissionsKeyspaceResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{233} +} + type ValidateSchemaKeyspaceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -13740,11 +14187,14 @@ type ValidateSchemaKeyspaceRequest struct { IncludeViews bool `protobuf:"varint,3,opt,name=include_views,json=includeViews,proto3" json:"include_views,omitempty"` SkipNoPrimary bool `protobuf:"varint,4,opt,name=skip_no_primary,json=skipNoPrimary,proto3" json:"skip_no_primary,omitempty"` IncludeVschema bool `protobuf:"varint,5,opt,name=include_vschema,json=includeVschema,proto3" json:"include_vschema,omitempty"` + // If you only want to validate a subset of the shards in the + // keyspace, then specify a list of shard names. + Shards []string `protobuf:"bytes,6,rep,name=shards,proto3" json:"shards,omitempty"` } func (x *ValidateSchemaKeyspaceRequest) Reset() { *x = ValidateSchemaKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[226] + mi := &file_vtctldata_proto_msgTypes[234] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13756,7 +14206,7 @@ func (x *ValidateSchemaKeyspaceRequest) String() string { func (*ValidateSchemaKeyspaceRequest) ProtoMessage() {} func (x *ValidateSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[226] + mi := &file_vtctldata_proto_msgTypes[234] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13769,7 +14219,7 @@ func (x *ValidateSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateSchemaKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateSchemaKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{226} + return file_vtctldata_proto_rawDescGZIP(), []int{234} } func (x *ValidateSchemaKeyspaceRequest) GetKeyspace() string { @@ -13807,6 +14257,13 @@ func (x *ValidateSchemaKeyspaceRequest) GetIncludeVschema() bool { return false } +func (x *ValidateSchemaKeyspaceRequest) GetShards() []string { + if x != nil { + return x.Shards + } + return nil +} + type ValidateSchemaKeyspaceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -13818,7 +14275,7 @@ type ValidateSchemaKeyspaceResponse struct { func (x *ValidateSchemaKeyspaceResponse) Reset() { *x = ValidateSchemaKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[227] + mi := &file_vtctldata_proto_msgTypes[235] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13830,7 +14287,7 @@ func (x *ValidateSchemaKeyspaceResponse) String() string { func (*ValidateSchemaKeyspaceResponse) ProtoMessage() {} func (x *ValidateSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[227] + mi := &file_vtctldata_proto_msgTypes[235] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13843,7 +14300,7 @@ func (x *ValidateSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateSchemaKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateSchemaKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{227} + return file_vtctldata_proto_rawDescGZIP(), []int{235} } func (x *ValidateSchemaKeyspaceResponse) GetResults() []string { @@ -13872,7 +14329,7 @@ type ValidateShardRequest struct { func (x *ValidateShardRequest) Reset() { *x = ValidateShardRequest{} - mi := &file_vtctldata_proto_msgTypes[228] + mi := &file_vtctldata_proto_msgTypes[236] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13884,7 +14341,7 @@ func (x *ValidateShardRequest) String() string { func (*ValidateShardRequest) ProtoMessage() {} func (x *ValidateShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[228] + mi := &file_vtctldata_proto_msgTypes[236] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13897,7 +14354,7 @@ func (x *ValidateShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateShardRequest.ProtoReflect.Descriptor instead. func (*ValidateShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{228} + return file_vtctldata_proto_rawDescGZIP(), []int{236} } func (x *ValidateShardRequest) GetKeyspace() string { @@ -13931,7 +14388,7 @@ type ValidateShardResponse struct { func (x *ValidateShardResponse) Reset() { *x = ValidateShardResponse{} - mi := &file_vtctldata_proto_msgTypes[229] + mi := &file_vtctldata_proto_msgTypes[237] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13943,7 +14400,7 @@ func (x *ValidateShardResponse) String() string { func (*ValidateShardResponse) ProtoMessage() {} func (x *ValidateShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[229] + mi := &file_vtctldata_proto_msgTypes[237] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13956,7 +14413,7 @@ func (x *ValidateShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateShardResponse.ProtoReflect.Descriptor instead. func (*ValidateShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{229} + return file_vtctldata_proto_rawDescGZIP(), []int{237} } func (x *ValidateShardResponse) GetResults() []string { @@ -13976,7 +14433,7 @@ type ValidateVersionKeyspaceRequest struct { func (x *ValidateVersionKeyspaceRequest) Reset() { *x = ValidateVersionKeyspaceRequest{} - mi := &file_vtctldata_proto_msgTypes[230] + mi := &file_vtctldata_proto_msgTypes[238] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13988,7 +14445,7 @@ func (x *ValidateVersionKeyspaceRequest) String() string { func (*ValidateVersionKeyspaceRequest) ProtoMessage() {} func (x *ValidateVersionKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[230] + mi := &file_vtctldata_proto_msgTypes[238] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14001,7 +14458,7 @@ func (x *ValidateVersionKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateVersionKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{230} + return file_vtctldata_proto_rawDescGZIP(), []int{238} } func (x *ValidateVersionKeyspaceRequest) GetKeyspace() string { @@ -14022,7 +14479,7 @@ type ValidateVersionKeyspaceResponse struct { func (x *ValidateVersionKeyspaceResponse) Reset() { *x = ValidateVersionKeyspaceResponse{} - mi := &file_vtctldata_proto_msgTypes[231] + mi := &file_vtctldata_proto_msgTypes[239] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14034,7 +14491,7 @@ func (x *ValidateVersionKeyspaceResponse) String() string { func (*ValidateVersionKeyspaceResponse) ProtoMessage() {} func (x *ValidateVersionKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[231] + mi := &file_vtctldata_proto_msgTypes[239] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14047,7 +14504,7 @@ func (x *ValidateVersionKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateVersionKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{231} + return file_vtctldata_proto_rawDescGZIP(), []int{239} } func (x *ValidateVersionKeyspaceResponse) GetResults() []string { @@ -14075,7 +14532,7 @@ type ValidateVersionShardRequest struct { func (x *ValidateVersionShardRequest) Reset() { *x = ValidateVersionShardRequest{} - mi := &file_vtctldata_proto_msgTypes[232] + mi := &file_vtctldata_proto_msgTypes[240] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14087,7 +14544,7 @@ func (x *ValidateVersionShardRequest) String() string { func (*ValidateVersionShardRequest) ProtoMessage() {} func (x *ValidateVersionShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[232] + mi := &file_vtctldata_proto_msgTypes[240] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14100,7 +14557,7 @@ func (x *ValidateVersionShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionShardRequest.ProtoReflect.Descriptor instead. func (*ValidateVersionShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{232} + return file_vtctldata_proto_rawDescGZIP(), []int{240} } func (x *ValidateVersionShardRequest) GetKeyspace() string { @@ -14127,7 +14584,7 @@ type ValidateVersionShardResponse struct { func (x *ValidateVersionShardResponse) Reset() { *x = ValidateVersionShardResponse{} - mi := &file_vtctldata_proto_msgTypes[233] + mi := &file_vtctldata_proto_msgTypes[241] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14139,7 +14596,7 @@ func (x *ValidateVersionShardResponse) String() string { func (*ValidateVersionShardResponse) ProtoMessage() {} func (x *ValidateVersionShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[233] + mi := &file_vtctldata_proto_msgTypes[241] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14152,7 +14609,7 @@ func (x *ValidateVersionShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionShardResponse.ProtoReflect.Descriptor instead. func (*ValidateVersionShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{233} + return file_vtctldata_proto_rawDescGZIP(), []int{241} } func (x *ValidateVersionShardResponse) GetResults() []string { @@ -14175,7 +14632,7 @@ type ValidateVSchemaRequest struct { func (x *ValidateVSchemaRequest) Reset() { *x = ValidateVSchemaRequest{} - mi := &file_vtctldata_proto_msgTypes[234] + mi := &file_vtctldata_proto_msgTypes[242] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14187,7 +14644,7 @@ func (x *ValidateVSchemaRequest) String() string { func (*ValidateVSchemaRequest) ProtoMessage() {} func (x *ValidateVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[234] + mi := &file_vtctldata_proto_msgTypes[242] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14200,7 +14657,7 @@ func (x *ValidateVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVSchemaRequest.ProtoReflect.Descriptor instead. func (*ValidateVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{234} + return file_vtctldata_proto_rawDescGZIP(), []int{242} } func (x *ValidateVSchemaRequest) GetKeyspace() string { @@ -14242,7 +14699,7 @@ type ValidateVSchemaResponse struct { func (x *ValidateVSchemaResponse) Reset() { *x = ValidateVSchemaResponse{} - mi := &file_vtctldata_proto_msgTypes[235] + mi := &file_vtctldata_proto_msgTypes[243] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14254,7 +14711,7 @@ func (x *ValidateVSchemaResponse) String() string { func (*ValidateVSchemaResponse) ProtoMessage() {} func (x *ValidateVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[235] + mi := &file_vtctldata_proto_msgTypes[243] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14267,7 +14724,7 @@ func (x *ValidateVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVSchemaResponse.ProtoReflect.Descriptor instead. func (*ValidateVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{235} + return file_vtctldata_proto_rawDescGZIP(), []int{243} } func (x *ValidateVSchemaResponse) GetResults() []string { @@ -14373,7 +14830,7 @@ type VDiffCreateRequest struct { func (x *VDiffCreateRequest) Reset() { *x = VDiffCreateRequest{} - mi := &file_vtctldata_proto_msgTypes[236] + mi := &file_vtctldata_proto_msgTypes[244] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14385,7 +14842,7 @@ func (x *VDiffCreateRequest) String() string { func (*VDiffCreateRequest) ProtoMessage() {} func (x *VDiffCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[236] + mi := &file_vtctldata_proto_msgTypes[244] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14398,7 +14855,7 @@ func (x *VDiffCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffCreateRequest.ProtoReflect.Descriptor instead. func (*VDiffCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{236} + return file_vtctldata_proto_rawDescGZIP(), []int{244} } func (x *VDiffCreateRequest) GetWorkflow() string { @@ -14567,7 +15024,7 @@ type VDiffCreateResponse struct { func (x *VDiffCreateResponse) Reset() { *x = VDiffCreateResponse{} - mi := &file_vtctldata_proto_msgTypes[237] + mi := &file_vtctldata_proto_msgTypes[245] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14579,7 +15036,7 @@ func (x *VDiffCreateResponse) String() string { func (*VDiffCreateResponse) ProtoMessage() {} func (x *VDiffCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[237] + mi := &file_vtctldata_proto_msgTypes[245] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14592,7 +15049,7 @@ func (x *VDiffCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffCreateResponse.ProtoReflect.Descriptor instead. func (*VDiffCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{237} + return file_vtctldata_proto_rawDescGZIP(), []int{245} } func (x *VDiffCreateResponse) GetUUID() string { @@ -14615,7 +15072,7 @@ type VDiffDeleteRequest struct { func (x *VDiffDeleteRequest) Reset() { *x = VDiffDeleteRequest{} - mi := &file_vtctldata_proto_msgTypes[238] + mi := &file_vtctldata_proto_msgTypes[246] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14627,7 +15084,7 @@ func (x *VDiffDeleteRequest) String() string { func (*VDiffDeleteRequest) ProtoMessage() {} func (x *VDiffDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[238] + mi := &file_vtctldata_proto_msgTypes[246] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14640,7 +15097,7 @@ func (x *VDiffDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffDeleteRequest.ProtoReflect.Descriptor instead. func (*VDiffDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{238} + return file_vtctldata_proto_rawDescGZIP(), []int{246} } func (x *VDiffDeleteRequest) GetWorkflow() string { @@ -14672,7 +15129,7 @@ type VDiffDeleteResponse struct { func (x *VDiffDeleteResponse) Reset() { *x = VDiffDeleteResponse{} - mi := &file_vtctldata_proto_msgTypes[239] + mi := &file_vtctldata_proto_msgTypes[247] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14684,7 +15141,7 @@ func (x *VDiffDeleteResponse) String() string { func (*VDiffDeleteResponse) ProtoMessage() {} func (x *VDiffDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[239] + mi := &file_vtctldata_proto_msgTypes[247] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14697,7 +15154,7 @@ func (x *VDiffDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffDeleteResponse.ProtoReflect.Descriptor instead. func (*VDiffDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{239} + return file_vtctldata_proto_rawDescGZIP(), []int{247} } type VDiffResumeRequest struct { @@ -14713,7 +15170,7 @@ type VDiffResumeRequest struct { func (x *VDiffResumeRequest) Reset() { *x = VDiffResumeRequest{} - mi := &file_vtctldata_proto_msgTypes[240] + mi := &file_vtctldata_proto_msgTypes[248] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14725,7 +15182,7 @@ func (x *VDiffResumeRequest) String() string { func (*VDiffResumeRequest) ProtoMessage() {} func (x *VDiffResumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[240] + mi := &file_vtctldata_proto_msgTypes[248] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14738,7 +15195,7 @@ func (x *VDiffResumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffResumeRequest.ProtoReflect.Descriptor instead. func (*VDiffResumeRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{240} + return file_vtctldata_proto_rawDescGZIP(), []int{248} } func (x *VDiffResumeRequest) GetWorkflow() string { @@ -14777,7 +15234,7 @@ type VDiffResumeResponse struct { func (x *VDiffResumeResponse) Reset() { *x = VDiffResumeResponse{} - mi := &file_vtctldata_proto_msgTypes[241] + mi := &file_vtctldata_proto_msgTypes[249] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14789,7 +15246,7 @@ func (x *VDiffResumeResponse) String() string { func (*VDiffResumeResponse) ProtoMessage() {} func (x *VDiffResumeResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[241] + mi := &file_vtctldata_proto_msgTypes[249] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14802,7 +15259,7 @@ func (x *VDiffResumeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffResumeResponse.ProtoReflect.Descriptor instead. func (*VDiffResumeResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{241} + return file_vtctldata_proto_rawDescGZIP(), []int{249} } type VDiffShowRequest struct { @@ -14818,7 +15275,7 @@ type VDiffShowRequest struct { func (x *VDiffShowRequest) Reset() { *x = VDiffShowRequest{} - mi := &file_vtctldata_proto_msgTypes[242] + mi := &file_vtctldata_proto_msgTypes[250] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14830,7 +15287,7 @@ func (x *VDiffShowRequest) String() string { func (*VDiffShowRequest) ProtoMessage() {} func (x *VDiffShowRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[242] + mi := &file_vtctldata_proto_msgTypes[250] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14843,7 +15300,7 @@ func (x *VDiffShowRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffShowRequest.ProtoReflect.Descriptor instead. func (*VDiffShowRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{242} + return file_vtctldata_proto_rawDescGZIP(), []int{250} } func (x *VDiffShowRequest) GetWorkflow() string { @@ -14878,7 +15335,7 @@ type VDiffShowResponse struct { func (x *VDiffShowResponse) Reset() { *x = VDiffShowResponse{} - mi := &file_vtctldata_proto_msgTypes[243] + mi := &file_vtctldata_proto_msgTypes[251] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14890,7 +15347,7 @@ func (x *VDiffShowResponse) String() string { func (*VDiffShowResponse) ProtoMessage() {} func (x *VDiffShowResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[243] + mi := &file_vtctldata_proto_msgTypes[251] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14903,7 +15360,7 @@ func (x *VDiffShowResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffShowResponse.ProtoReflect.Descriptor instead. func (*VDiffShowResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{243} + return file_vtctldata_proto_rawDescGZIP(), []int{251} } func (x *VDiffShowResponse) GetTabletResponses() map[string]*tabletmanagerdata.VDiffResponse { @@ -14926,7 +15383,7 @@ type VDiffStopRequest struct { func (x *VDiffStopRequest) Reset() { *x = VDiffStopRequest{} - mi := &file_vtctldata_proto_msgTypes[244] + mi := &file_vtctldata_proto_msgTypes[252] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14938,7 +15395,7 @@ func (x *VDiffStopRequest) String() string { func (*VDiffStopRequest) ProtoMessage() {} func (x *VDiffStopRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[244] + mi := &file_vtctldata_proto_msgTypes[252] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14951,7 +15408,7 @@ func (x *VDiffStopRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffStopRequest.ProtoReflect.Descriptor instead. func (*VDiffStopRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{244} + return file_vtctldata_proto_rawDescGZIP(), []int{252} } func (x *VDiffStopRequest) GetWorkflow() string { @@ -14990,7 +15447,7 @@ type VDiffStopResponse struct { func (x *VDiffStopResponse) Reset() { *x = VDiffStopResponse{} - mi := &file_vtctldata_proto_msgTypes[245] + mi := &file_vtctldata_proto_msgTypes[253] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15002,7 +15459,7 @@ func (x *VDiffStopResponse) String() string { func (*VDiffStopResponse) ProtoMessage() {} func (x *VDiffStopResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[245] + mi := &file_vtctldata_proto_msgTypes[253] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15015,7 +15472,7 @@ func (x *VDiffStopResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffStopResponse.ProtoReflect.Descriptor instead. func (*VDiffStopResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{245} + return file_vtctldata_proto_rawDescGZIP(), []int{253} } type WorkflowDeleteRequest struct { @@ -15036,7 +15493,7 @@ type WorkflowDeleteRequest struct { func (x *WorkflowDeleteRequest) Reset() { *x = WorkflowDeleteRequest{} - mi := &file_vtctldata_proto_msgTypes[246] + mi := &file_vtctldata_proto_msgTypes[254] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15048,7 +15505,7 @@ func (x *WorkflowDeleteRequest) String() string { func (*WorkflowDeleteRequest) ProtoMessage() {} func (x *WorkflowDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[246] + mi := &file_vtctldata_proto_msgTypes[254] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15061,7 +15518,7 @@ func (x *WorkflowDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowDeleteRequest.ProtoReflect.Descriptor instead. func (*WorkflowDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{246} + return file_vtctldata_proto_rawDescGZIP(), []int{254} } func (x *WorkflowDeleteRequest) GetKeyspace() string { @@ -15117,7 +15574,7 @@ type WorkflowDeleteResponse struct { func (x *WorkflowDeleteResponse) Reset() { *x = WorkflowDeleteResponse{} - mi := &file_vtctldata_proto_msgTypes[247] + mi := &file_vtctldata_proto_msgTypes[255] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15129,7 +15586,7 @@ func (x *WorkflowDeleteResponse) String() string { func (*WorkflowDeleteResponse) ProtoMessage() {} func (x *WorkflowDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[247] + mi := &file_vtctldata_proto_msgTypes[255] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15142,7 +15599,7 @@ func (x *WorkflowDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowDeleteResponse.ProtoReflect.Descriptor instead. func (*WorkflowDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{247} + return file_vtctldata_proto_rawDescGZIP(), []int{255} } func (x *WorkflowDeleteResponse) GetSummary() string { @@ -15171,7 +15628,7 @@ type WorkflowStatusRequest struct { func (x *WorkflowStatusRequest) Reset() { *x = WorkflowStatusRequest{} - mi := &file_vtctldata_proto_msgTypes[248] + mi := &file_vtctldata_proto_msgTypes[256] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15183,7 +15640,7 @@ func (x *WorkflowStatusRequest) String() string { func (*WorkflowStatusRequest) ProtoMessage() {} func (x *WorkflowStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[248] + mi := &file_vtctldata_proto_msgTypes[256] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15196,7 +15653,7 @@ func (x *WorkflowStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowStatusRequest.ProtoReflect.Descriptor instead. func (*WorkflowStatusRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{248} + return file_vtctldata_proto_rawDescGZIP(), []int{256} } func (x *WorkflowStatusRequest) GetKeyspace() string { @@ -15233,7 +15690,7 @@ type WorkflowStatusResponse struct { func (x *WorkflowStatusResponse) Reset() { *x = WorkflowStatusResponse{} - mi := &file_vtctldata_proto_msgTypes[249] + mi := &file_vtctldata_proto_msgTypes[257] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15245,7 +15702,7 @@ func (x *WorkflowStatusResponse) String() string { func (*WorkflowStatusResponse) ProtoMessage() {} func (x *WorkflowStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[249] + mi := &file_vtctldata_proto_msgTypes[257] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15258,7 +15715,7 @@ func (x *WorkflowStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowStatusResponse.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{249} + return file_vtctldata_proto_rawDescGZIP(), []int{257} } func (x *WorkflowStatusResponse) GetTableCopyState() map[string]*WorkflowStatusResponse_TableCopyState { @@ -15303,7 +15760,7 @@ type WorkflowSwitchTrafficRequest struct { func (x *WorkflowSwitchTrafficRequest) Reset() { *x = WorkflowSwitchTrafficRequest{} - mi := &file_vtctldata_proto_msgTypes[250] + mi := &file_vtctldata_proto_msgTypes[258] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15315,7 +15772,7 @@ func (x *WorkflowSwitchTrafficRequest) String() string { func (*WorkflowSwitchTrafficRequest) ProtoMessage() {} func (x *WorkflowSwitchTrafficRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[250] + mi := &file_vtctldata_proto_msgTypes[258] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15328,7 +15785,7 @@ func (x *WorkflowSwitchTrafficRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowSwitchTrafficRequest.ProtoReflect.Descriptor instead. func (*WorkflowSwitchTrafficRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{250} + return file_vtctldata_proto_rawDescGZIP(), []int{258} } func (x *WorkflowSwitchTrafficRequest) GetKeyspace() string { @@ -15428,7 +15885,7 @@ type WorkflowSwitchTrafficResponse struct { func (x *WorkflowSwitchTrafficResponse) Reset() { *x = WorkflowSwitchTrafficResponse{} - mi := &file_vtctldata_proto_msgTypes[251] + mi := &file_vtctldata_proto_msgTypes[259] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15440,7 +15897,7 @@ func (x *WorkflowSwitchTrafficResponse) String() string { func (*WorkflowSwitchTrafficResponse) ProtoMessage() {} func (x *WorkflowSwitchTrafficResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[251] + mi := &file_vtctldata_proto_msgTypes[259] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15453,7 +15910,7 @@ func (x *WorkflowSwitchTrafficResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowSwitchTrafficResponse.ProtoReflect.Descriptor instead. func (*WorkflowSwitchTrafficResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{251} + return file_vtctldata_proto_rawDescGZIP(), []int{259} } func (x *WorkflowSwitchTrafficResponse) GetSummary() string { @@ -15497,7 +15954,7 @@ type WorkflowUpdateRequest struct { func (x *WorkflowUpdateRequest) Reset() { *x = WorkflowUpdateRequest{} - mi := &file_vtctldata_proto_msgTypes[252] + mi := &file_vtctldata_proto_msgTypes[260] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15509,7 +15966,7 @@ func (x *WorkflowUpdateRequest) String() string { func (*WorkflowUpdateRequest) ProtoMessage() {} func (x *WorkflowUpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[252] + mi := &file_vtctldata_proto_msgTypes[260] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15522,7 +15979,7 @@ func (x *WorkflowUpdateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowUpdateRequest.ProtoReflect.Descriptor instead. func (*WorkflowUpdateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{252} + return file_vtctldata_proto_rawDescGZIP(), []int{260} } func (x *WorkflowUpdateRequest) GetKeyspace() string { @@ -15550,7 +16007,7 @@ type WorkflowUpdateResponse struct { func (x *WorkflowUpdateResponse) Reset() { *x = WorkflowUpdateResponse{} - mi := &file_vtctldata_proto_msgTypes[253] + mi := &file_vtctldata_proto_msgTypes[261] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15562,7 +16019,7 @@ func (x *WorkflowUpdateResponse) String() string { func (*WorkflowUpdateResponse) ProtoMessage() {} func (x *WorkflowUpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[253] + mi := &file_vtctldata_proto_msgTypes[261] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15575,7 +16032,7 @@ func (x *WorkflowUpdateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowUpdateResponse.ProtoReflect.Descriptor instead. func (*WorkflowUpdateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{253} + return file_vtctldata_proto_rawDescGZIP(), []int{261} } func (x *WorkflowUpdateResponse) GetSummary() string { @@ -15600,7 +16057,7 @@ type GetMirrorRulesRequest struct { func (x *GetMirrorRulesRequest) Reset() { *x = GetMirrorRulesRequest{} - mi := &file_vtctldata_proto_msgTypes[254] + mi := &file_vtctldata_proto_msgTypes[262] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15612,7 +16069,7 @@ func (x *GetMirrorRulesRequest) String() string { func (*GetMirrorRulesRequest) ProtoMessage() {} func (x *GetMirrorRulesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[254] + mi := &file_vtctldata_proto_msgTypes[262] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15625,7 +16082,7 @@ func (x *GetMirrorRulesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMirrorRulesRequest.ProtoReflect.Descriptor instead. func (*GetMirrorRulesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{254} + return file_vtctldata_proto_rawDescGZIP(), []int{262} } type GetMirrorRulesResponse struct { @@ -15638,7 +16095,7 @@ type GetMirrorRulesResponse struct { func (x *GetMirrorRulesResponse) Reset() { *x = GetMirrorRulesResponse{} - mi := &file_vtctldata_proto_msgTypes[255] + mi := &file_vtctldata_proto_msgTypes[263] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15650,7 +16107,7 @@ func (x *GetMirrorRulesResponse) String() string { func (*GetMirrorRulesResponse) ProtoMessage() {} func (x *GetMirrorRulesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[255] + mi := &file_vtctldata_proto_msgTypes[263] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15663,7 +16120,7 @@ func (x *GetMirrorRulesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMirrorRulesResponse.ProtoReflect.Descriptor instead. func (*GetMirrorRulesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{255} + return file_vtctldata_proto_rawDescGZIP(), []int{263} } func (x *GetMirrorRulesResponse) GetMirrorRules() *vschema.MirrorRules { @@ -15686,7 +16143,7 @@ type WorkflowMirrorTrafficRequest struct { func (x *WorkflowMirrorTrafficRequest) Reset() { *x = WorkflowMirrorTrafficRequest{} - mi := &file_vtctldata_proto_msgTypes[256] + mi := &file_vtctldata_proto_msgTypes[264] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15698,7 +16155,7 @@ func (x *WorkflowMirrorTrafficRequest) String() string { func (*WorkflowMirrorTrafficRequest) ProtoMessage() {} func (x *WorkflowMirrorTrafficRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[256] + mi := &file_vtctldata_proto_msgTypes[264] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15711,7 +16168,7 @@ func (x *WorkflowMirrorTrafficRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowMirrorTrafficRequest.ProtoReflect.Descriptor instead. func (*WorkflowMirrorTrafficRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{256} + return file_vtctldata_proto_rawDescGZIP(), []int{264} } func (x *WorkflowMirrorTrafficRequest) GetKeyspace() string { @@ -15754,7 +16211,7 @@ type WorkflowMirrorTrafficResponse struct { func (x *WorkflowMirrorTrafficResponse) Reset() { *x = WorkflowMirrorTrafficResponse{} - mi := &file_vtctldata_proto_msgTypes[257] + mi := &file_vtctldata_proto_msgTypes[265] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15766,7 +16223,7 @@ func (x *WorkflowMirrorTrafficResponse) String() string { func (*WorkflowMirrorTrafficResponse) ProtoMessage() {} func (x *WorkflowMirrorTrafficResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[257] + mi := &file_vtctldata_proto_msgTypes[265] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15779,7 +16236,7 @@ func (x *WorkflowMirrorTrafficResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowMirrorTrafficResponse.ProtoReflect.Descriptor instead. func (*WorkflowMirrorTrafficResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{257} + return file_vtctldata_proto_rawDescGZIP(), []int{265} } func (x *WorkflowMirrorTrafficResponse) GetSummary() string { @@ -15814,7 +16271,7 @@ type Workflow_ReplicationLocation struct { func (x *Workflow_ReplicationLocation) Reset() { *x = Workflow_ReplicationLocation{} - mi := &file_vtctldata_proto_msgTypes[260] + mi := &file_vtctldata_proto_msgTypes[268] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15826,7 +16283,7 @@ func (x *Workflow_ReplicationLocation) String() string { func (*Workflow_ReplicationLocation) ProtoMessage() {} func (x *Workflow_ReplicationLocation) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[260] + mi := &file_vtctldata_proto_msgTypes[268] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15868,7 +16325,7 @@ type Workflow_ShardStream struct { func (x *Workflow_ShardStream) Reset() { *x = Workflow_ShardStream{} - mi := &file_vtctldata_proto_msgTypes[261] + mi := &file_vtctldata_proto_msgTypes[269] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15880,7 +16337,7 @@ func (x *Workflow_ShardStream) String() string { func (*Workflow_ShardStream) ProtoMessage() {} func (x *Workflow_ShardStream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[261] + mi := &file_vtctldata_proto_msgTypes[269] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15954,7 +16411,7 @@ type Workflow_Stream struct { func (x *Workflow_Stream) Reset() { *x = Workflow_Stream{} - mi := &file_vtctldata_proto_msgTypes[262] + mi := &file_vtctldata_proto_msgTypes[270] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15966,7 +16423,7 @@ func (x *Workflow_Stream) String() string { func (*Workflow_Stream) ProtoMessage() {} func (x *Workflow_Stream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[262] + mi := &file_vtctldata_proto_msgTypes[270] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16134,7 +16591,7 @@ type Workflow_Stream_CopyState struct { func (x *Workflow_Stream_CopyState) Reset() { *x = Workflow_Stream_CopyState{} - mi := &file_vtctldata_proto_msgTypes[263] + mi := &file_vtctldata_proto_msgTypes[271] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16146,7 +16603,7 @@ func (x *Workflow_Stream_CopyState) String() string { func (*Workflow_Stream_CopyState) ProtoMessage() {} func (x *Workflow_Stream_CopyState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[263] + mi := &file_vtctldata_proto_msgTypes[271] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16200,7 +16657,7 @@ type Workflow_Stream_Log struct { func (x *Workflow_Stream_Log) Reset() { *x = Workflow_Stream_Log{} - mi := &file_vtctldata_proto_msgTypes[264] + mi := &file_vtctldata_proto_msgTypes[272] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16212,7 +16669,7 @@ func (x *Workflow_Stream_Log) String() string { func (*Workflow_Stream_Log) ProtoMessage() {} func (x *Workflow_Stream_Log) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[264] + mi := &file_vtctldata_proto_msgTypes[272] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16295,7 +16752,7 @@ type Workflow_Stream_ThrottlerStatus struct { func (x *Workflow_Stream_ThrottlerStatus) Reset() { *x = Workflow_Stream_ThrottlerStatus{} - mi := &file_vtctldata_proto_msgTypes[265] + mi := &file_vtctldata_proto_msgTypes[273] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16307,7 +16764,7 @@ func (x *Workflow_Stream_ThrottlerStatus) String() string { func (*Workflow_Stream_ThrottlerStatus) ProtoMessage() {} func (x *Workflow_Stream_ThrottlerStatus) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[265] + mi := &file_vtctldata_proto_msgTypes[273] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16347,7 +16804,7 @@ type ApplyVSchemaResponse_ParamList struct { func (x *ApplyVSchemaResponse_ParamList) Reset() { *x = ApplyVSchemaResponse_ParamList{} - mi := &file_vtctldata_proto_msgTypes[268] + mi := &file_vtctldata_proto_msgTypes[276] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16359,7 +16816,7 @@ func (x *ApplyVSchemaResponse_ParamList) String() string { func (*ApplyVSchemaResponse_ParamList) ProtoMessage() {} func (x *ApplyVSchemaResponse_ParamList) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[268] + mi := &file_vtctldata_proto_msgTypes[276] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16392,7 +16849,7 @@ type GetSrvKeyspaceNamesResponse_NameList struct { func (x *GetSrvKeyspaceNamesResponse_NameList) Reset() { *x = GetSrvKeyspaceNamesResponse_NameList{} - mi := &file_vtctldata_proto_msgTypes[280] + mi := &file_vtctldata_proto_msgTypes[288] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16404,7 +16861,7 @@ func (x *GetSrvKeyspaceNamesResponse_NameList) String() string { func (*GetSrvKeyspaceNamesResponse_NameList) ProtoMessage() {} func (x *GetSrvKeyspaceNamesResponse_NameList) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[280] + mi := &file_vtctldata_proto_msgTypes[288] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16417,7 +16874,7 @@ func (x *GetSrvKeyspaceNamesResponse_NameList) ProtoReflect() protoreflect.Messa // Deprecated: Use GetSrvKeyspaceNamesResponse_NameList.ProtoReflect.Descriptor instead. func (*GetSrvKeyspaceNamesResponse_NameList) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{99, 1} + return file_vtctldata_proto_rawDescGZIP(), []int{101, 1} } func (x *GetSrvKeyspaceNamesResponse_NameList) GetNames() []string { @@ -16439,7 +16896,7 @@ type MoveTablesCreateResponse_TabletInfo struct { func (x *MoveTablesCreateResponse_TabletInfo) Reset() { *x = MoveTablesCreateResponse_TabletInfo{} - mi := &file_vtctldata_proto_msgTypes[284] + mi := &file_vtctldata_proto_msgTypes[292] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16451,7 +16908,7 @@ func (x *MoveTablesCreateResponse_TabletInfo) String() string { func (*MoveTablesCreateResponse_TabletInfo) ProtoMessage() {} func (x *MoveTablesCreateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[284] + mi := &file_vtctldata_proto_msgTypes[292] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16464,7 +16921,7 @@ func (x *MoveTablesCreateResponse_TabletInfo) ProtoReflect() protoreflect.Messag // Deprecated: Use MoveTablesCreateResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*MoveTablesCreateResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{152, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{158, 0} } func (x *MoveTablesCreateResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -16493,7 +16950,7 @@ type WorkflowDeleteResponse_TabletInfo struct { func (x *WorkflowDeleteResponse_TabletInfo) Reset() { *x = WorkflowDeleteResponse_TabletInfo{} - mi := &file_vtctldata_proto_msgTypes[294] + mi := &file_vtctldata_proto_msgTypes[302] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16505,7 +16962,7 @@ func (x *WorkflowDeleteResponse_TabletInfo) String() string { func (*WorkflowDeleteResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowDeleteResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[294] + mi := &file_vtctldata_proto_msgTypes[302] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16518,7 +16975,7 @@ func (x *WorkflowDeleteResponse_TabletInfo) ProtoReflect() protoreflect.Message // Deprecated: Use WorkflowDeleteResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*WorkflowDeleteResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{247, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{255, 0} } func (x *WorkflowDeleteResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -16550,7 +17007,7 @@ type WorkflowStatusResponse_TableCopyState struct { func (x *WorkflowStatusResponse_TableCopyState) Reset() { *x = WorkflowStatusResponse_TableCopyState{} - mi := &file_vtctldata_proto_msgTypes[295] + mi := &file_vtctldata_proto_msgTypes[303] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16562,7 +17019,7 @@ func (x *WorkflowStatusResponse_TableCopyState) String() string { func (*WorkflowStatusResponse_TableCopyState) ProtoMessage() {} func (x *WorkflowStatusResponse_TableCopyState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[295] + mi := &file_vtctldata_proto_msgTypes[303] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16575,7 +17032,7 @@ func (x *WorkflowStatusResponse_TableCopyState) ProtoReflect() protoreflect.Mess // Deprecated: Use WorkflowStatusResponse_TableCopyState.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_TableCopyState) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{249, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{257, 0} } func (x *WorkflowStatusResponse_TableCopyState) GetRowsCopied() int64 { @@ -16635,7 +17092,7 @@ type WorkflowStatusResponse_ShardStreamState struct { func (x *WorkflowStatusResponse_ShardStreamState) Reset() { *x = WorkflowStatusResponse_ShardStreamState{} - mi := &file_vtctldata_proto_msgTypes[296] + mi := &file_vtctldata_proto_msgTypes[304] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16647,7 +17104,7 @@ func (x *WorkflowStatusResponse_ShardStreamState) String() string { func (*WorkflowStatusResponse_ShardStreamState) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreamState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[296] + mi := &file_vtctldata_proto_msgTypes[304] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16660,7 +17117,7 @@ func (x *WorkflowStatusResponse_ShardStreamState) ProtoReflect() protoreflect.Me // Deprecated: Use WorkflowStatusResponse_ShardStreamState.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_ShardStreamState) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{249, 1} + return file_vtctldata_proto_rawDescGZIP(), []int{257, 1} } func (x *WorkflowStatusResponse_ShardStreamState) GetId() int32 { @@ -16715,7 +17172,7 @@ type WorkflowStatusResponse_ShardStreams struct { func (x *WorkflowStatusResponse_ShardStreams) Reset() { *x = WorkflowStatusResponse_ShardStreams{} - mi := &file_vtctldata_proto_msgTypes[297] + mi := &file_vtctldata_proto_msgTypes[305] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16727,7 +17184,7 @@ func (x *WorkflowStatusResponse_ShardStreams) String() string { func (*WorkflowStatusResponse_ShardStreams) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreams) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[297] + mi := &file_vtctldata_proto_msgTypes[305] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16740,7 +17197,7 @@ func (x *WorkflowStatusResponse_ShardStreams) ProtoReflect() protoreflect.Messag // Deprecated: Use WorkflowStatusResponse_ShardStreams.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_ShardStreams) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{249, 2} + return file_vtctldata_proto_rawDescGZIP(), []int{257, 2} } func (x *WorkflowStatusResponse_ShardStreams) GetStreams() []*WorkflowStatusResponse_ShardStreamState { @@ -16763,7 +17220,7 @@ type WorkflowUpdateResponse_TabletInfo struct { func (x *WorkflowUpdateResponse_TabletInfo) Reset() { *x = WorkflowUpdateResponse_TabletInfo{} - mi := &file_vtctldata_proto_msgTypes[300] + mi := &file_vtctldata_proto_msgTypes[308] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16775,7 +17232,7 @@ func (x *WorkflowUpdateResponse_TabletInfo) String() string { func (*WorkflowUpdateResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowUpdateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[300] + mi := &file_vtctldata_proto_msgTypes[308] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16788,7 +17245,7 @@ func (x *WorkflowUpdateResponse_TabletInfo) ProtoReflect() protoreflect.Message // Deprecated: Use WorkflowUpdateResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*WorkflowUpdateResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{253, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{261, 0} } func (x *WorkflowUpdateResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -17532,1162 +17989,705 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdd, 0x02, 0x0a, - 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, - 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x12, 0x2f, 0x0a, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, - 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x16, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x31, 0x0a, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x5f, 0x64, 0x62, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x69, 0x64, - 0x65, 0x63, 0x61, 0x72, 0x44, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, - 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0x49, 0x0a, 0x16, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8a, 0x03, 0x0a, + 0x16, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x13, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x11, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, + 0x77, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x31, 0x0a, 0x14, 0x64, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x11, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x6f, 0x70, + 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x02, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, + 0x73, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x0d, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, + 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2b, 0x0a, + 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x69, + 0x64, 0x65, 0x63, 0x61, 0x72, 0x5f, 0x64, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x44, 0x62, 0x4e, 0x61, + 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, + 0x08, 0x06, 0x10, 0x07, 0x22, 0x49, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, + 0x8c, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0xa0, + 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x8c, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, - 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0xa0, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x26, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x5f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, 0x68, 0x61, 0x72, 0x64, 0x41, 0x6c, 0x72, 0x65, - 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x41, 0x0a, 0x15, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, - 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x67, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, + 0x30, 0x0a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, + 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, + 0x73, 0x22, 0x41, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, + 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1a, 0x0a, + 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x67, 0x0a, 0x15, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, + 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x12, 0x26, 0x0a, 0x0f, + 0x65, 0x76, 0x65, 0x6e, 0x5f, 0x69, 0x66, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x76, 0x65, 0x6e, 0x49, 0x66, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, 0x56, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, + 0x6c, 0x22, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, 0x56, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, + 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xc3, 0x03, 0x0a, 0x1d, 0x45, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3e, 0x0a, + 0x0f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0e, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x44, 0x0a, + 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, + 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, + 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x63, + 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x70, 0x72, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x65, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x6f, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x66, 0x6f, 0x72, + 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x11, 0x77, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x40, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0xbc, 0x01, 0x0a, 0x1e, 0x45, 0x6d, 0x65, 0x72, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, - 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, - 0x73, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, - 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, - 0x73, 0x69, 0x76, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x76, 0x65, 0x6e, 0x5f, 0x69, 0x66, 0x5f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, - 0x76, 0x65, 0x6e, 0x49, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, - 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc3, 0x03, 0x0a, 0x1d, 0x45, 0x6d, - 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, - 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3e, 0x0a, 0x0f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, - 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0e, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x70, - 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x63, 0x65, 0x6c, - 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x19, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, - 0x65, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x14, - 0x77, 0x61, 0x69, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x77, 0x61, 0x69, 0x74, - 0x46, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x40, 0x0a, - 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, - 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, - 0xbc, 0x01, 0x0a, 0x1e, 0x45, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, - 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, + 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, + 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, + 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x19, + 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x75, 0x73, 0x65, 0x50, 0x6f, 0x6f, 0x6c, 0x22, 0x47, 0x0a, 0x19, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, + 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x47, 0x0a, 0x19, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xa0, - 0x01, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, - 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x12, 0x55, 0x0a, 0x13, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x11, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x48, 0x6f, + 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x13, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x47, 0x0a, 0x0b, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x68, + 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xd4, 0x01, 0x0a, 0x1d, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, + 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, - 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, - 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x6f, - 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x50, 0x6f, 0x6f, - 0x6c, 0x22, 0x47, 0x0a, 0x19, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x18, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x71, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x22, 0x47, 0x0a, 0x19, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, - 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x55, 0x0a, 0x13, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x11, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x5e, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x68, 0x6f, 0x6f, 0x6b, - 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x22, 0xd4, 0x01, 0x0a, 0x1d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, - 0x74, 0x69, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, - 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x10, 0x0a, - 0x03, 0x73, 0x71, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x12, - 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x6f, - 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x4e, 0x0a, 0x1e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, - 0x42, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x1e, 0x46, 0x69, 0x6e, 0x64, - 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x1f, 0x46, 0x69, 0x6e, 0x64, 0x41, - 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x1a, 0x4b, 0x0a, 0x0b, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x54, 0x0a, 0x22, 0x46, 0x6f, 0x72, 0x63, 0x65, - 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xeb, 0x01, - 0x0a, 0x23, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x47, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, - 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9e, 0x01, 0x0a, 0x11, - 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, - 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x64, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x44, 0x0a, 0x12, - 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x46, 0x0a, 0x13, - 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, - 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, - 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x30, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb6, 0x01, 0x0a, 0x17, - 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, - 0x65, 0x73, 0x1a, 0x50, 0x0a, 0x0c, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, - 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x50, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x4c, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, - 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x14, 0x47, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x30, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x22, 0x51, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x22, 0x5a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, - 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, - 0x20, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x76, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x16, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x52, 0x14, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x55, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, - 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xb0, 0x02, 0x0a, 0x10, 0x47, - 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x28, 0x0a, - 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, - 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x4f, 0x6e, 0x6c, - 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x50, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x44, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, - 0xb8, 0x02, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x2b, - 0x0a, 0x11, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, - 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x18, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, - 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x22, 0x59, 0x0a, 0x1b, 0x47, 0x65, - 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x64, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x83, 0x02, 0x0a, 0x1b, - 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x19, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x62, 0x79, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x16, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x1a, 0x65, 0x0a, 0x1b, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, - 0x43, 0x65, 0x6c, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, - 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x4c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x22, - 0x3a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x47, - 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1c, 0x47, 0x65, - 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x1b, 0x47, - 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x05, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x1a, 0x69, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x22, 0x4e, 0x0a, 0x1e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x22, 0x3c, 0x0a, 0x1e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xbe, + 0x01, 0x0a, 0x1f, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, + 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x73, 0x1a, 0x4b, 0x0a, 0x0b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, - 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x20, - 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x22, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xcc, 0x01, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x34, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x1a, 0x56, 0x0a, 0x11, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe4, 0x03, 0x0a, 0x1c, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, - 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, - 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x63, - 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x53, 0x65, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, - 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x53, 0x65, 0x6c, 0x66, 0x12, 0x2f, 0x0a, 0x14, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, - 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x11, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x3f, 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, - 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, - 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x11, 0x61, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x22, 0x1f, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, - 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, - 0x4e, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x73, 0x72, 0x76, 0x5f, - 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x52, 0x0a, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, - 0x2d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xc5, - 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x0d, 0x73, 0x72, 0x76, - 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x73, 0x1a, 0x53, 0x0a, 0x10, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x22, 0x3d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x22, 0xe8, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x54, 0x0a, 0x22, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xeb, 0x01, 0x0a, 0x23, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, + 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, + 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, + 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x47, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, + 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, + 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, + 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x9e, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, - 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, - 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x40, - 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, - 0x22, 0x55, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, - 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x63, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x54, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, - 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x5f, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x61, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x46, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x52, - 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x80, 0x01, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, - 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, - 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5f, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x55, - 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x62, 0x61, 0x6e, - 0x64, 0x6f, 0x6e, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, - 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x41, 0x67, 0x65, 0x22, 0x63, 0x0a, 0x21, 0x47, 0x65, 0x74, - 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, - 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2f, - 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x74, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, - 0xa0, 0x01, 0x0a, 0x15, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x22, 0x63, - 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x64, 0x74, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, - 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, - 0x6e, 0x74, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x43, 0x6f, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2f, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x22, 0x4d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x22, 0x2e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0xc6, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6e, - 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, - 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, - 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, - 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, - 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x17, 0x49, - 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, + 0x0e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x22, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x79, + 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, + 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x19, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x30, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x65, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, + 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0xb6, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x49, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x1a, 0x50, 0x0a, 0x0c, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x50, 0x0a, 0x14, + 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, + 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x4c, + 0x0a, 0x15, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x15, 0x0a, 0x13, + 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x30, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x51, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x5a, 0x0a, 0x16, 0x47, + 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x76, 0x0a, 0x1f, 0x47, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x16, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x14, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x55, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x22, 0xb0, 0x02, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, + 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x6f, + 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x50, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0xb8, 0x02, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x52, 0x0a, 0x1a, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x17, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x45, 0x6c, 0x65, 0x63, - 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x42, 0x0a, 0x18, 0x49, 0x6e, 0x69, 0x74, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x4e, 0x0a, 0x1c, - 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdf, 0x01, 0x0a, - 0x1d, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, - 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, - 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x75, 0x6e, 0x63, - 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, - 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xff, - 0x02, 0x0a, 0x19, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x76, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x76, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x42, 0x0a, 0x1e, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x65, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x77, 0x69, 0x74, - 0x68, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x63, - 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, - 0x57, 0x69, 0x74, 0x68, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x22, 0x1c, 0x0a, 0x1a, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x77, - 0x0a, 0x1e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4c, 0x0a, 0x1f, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, - 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, - 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x18, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x1b, 0x0a, - 0x19, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x05, 0x0a, 0x14, 0x4d, - 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, - 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, - 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x09, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, - 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, - 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, - 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, - 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, - 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, - 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, - 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, - 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, - 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, - 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xe6, 0x01, 0x0a, 0x16, 0x4d, - 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, - 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, - 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, - 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, - 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, - 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, - 0x52, 0x75, 0x6e, 0x22, 0x5b, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, - 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x22, 0x85, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, - 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, - 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x70, - 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, - 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, - 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x19, 0x0a, 0x17, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x4d, 0x6f, - 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, - 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x70, 0x6f, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x72, - 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x52, - 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x29, 0x0a, 0x11, 0x4d, - 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x82, 0x07, 0x0a, 0x17, 0x4d, 0x6f, 0x76, 0x65, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, - 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, - 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x07, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, - 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, - 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, - 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, - 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, - 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, - 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, - 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, - 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, - 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x63, 0x6f, - 0x70, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, - 0x43, 0x6f, 0x70, 0x79, 0x12, 0x45, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x18, - 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x48, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, - 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x22, 0x81, 0x02, 0x0a, 0x19, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, - 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, - 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, - 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0x5e, 0x0a, 0x1a, 0x4d, 0x6f, 0x76, 0x65, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x69, 0x6e, 0x67, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd6, 0x03, 0x0a, - 0x1b, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x10, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, + 0x0a, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x6b, + 0x69, 0x70, 0x22, 0x59, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x64, 0x0a, + 0x1a, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x22, 0x83, 0x02, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x19, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x79, 0x5f, 0x63, 0x65, 0x6c, 0x6c, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x16, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x43, 0x65, + 0x6c, 0x6c, 0x1a, 0x65, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, - 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x0d, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x5f, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0c, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x4c, 0x0a, 0x19, 0x74, 0x6f, 0x6c, 0x65, - 0x72, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x74, - 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, - 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x65, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0xba, 0x01, 0x0a, 0x1c, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, - 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x6d, - 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, - 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, - 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x22, 0x74, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x72, - 0x74, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x1e, 0x0a, 0x1c, 0x52, 0x65, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x0a, 0x1a, 0x52, 0x65, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x1d, 0x0a, 0x1b, - 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x0a, 0x13, 0x52, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x32, + 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x47, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x69, 0x0a, 0x0a, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x20, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, + 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x59, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, + 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x56, 0x0a, 0x11, 0x53, + 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x72, 0x76, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xe4, 0x03, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x63, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x74, 0x12, 0x2d, 0x0a, + 0x13, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x73, 0x65, 0x6c, 0x66, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x2f, 0x0a, 0x14, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x3f, 0x0a, + 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x0c, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x12, 0x1f, + 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, + 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x61, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x1f, 0x0a, 0x1d, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x47, + 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x4e, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, + 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x35, 0x0a, 0x0c, 0x73, 0x72, 0x76, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0a, 0x73, 0x72, 0x76, + 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x2d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, + 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, + 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x56, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x56, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x73, 0x72, + 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x1a, 0x53, 0x0a, 0x10, 0x53, 0x72, 0x76, + 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x16, 0x0a, 0x14, - 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x1b, 0x52, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, - 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, - 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x74, - 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x64, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, 0x72, 0x74, 0x69, - 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x0a, 0x1b, 0x52, 0x65, - 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, - 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x46, 0x0a, 0x1c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xbc, 0x01, - 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x23, 0x0a, 0x0d, - 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, - 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x43, 0x0a, 0x19, - 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, - 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x22, 0x5b, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, - 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7f, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, - 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, - 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, - 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, - 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, - 0x69, 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, - 0x0a, 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0x7b, 0x0a, 0x16, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x22, 0xd6, 0x04, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, - 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, - 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, - 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, - 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, - 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, - 0x43, 0x6f, 0x70, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, - 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb8, 0x02, 0x0a, - 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x12, 0x2d, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, - 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, - 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, - 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x3d, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x28, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0xe8, 0x01, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, + 0x69, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, + 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, + 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, + 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x4d, 0x0a, 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, + 0x63, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x22, 0x5f, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, + 0x61, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, + 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x46, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, + 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2b, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x80, 0x01, + 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x22, 0x5f, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x5f, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x41, 0x67, + 0x65, 0x22, 0x63, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, + 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2f, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0xa0, 0x01, 0x0a, 0x15, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, + 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x1a, 0x47, + 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x22, 0x63, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x43, + 0x6f, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4d, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x2e, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0xc6, + 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, - 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, + 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f, + 0x6e, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x6c, 0x79, + 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x21, 0x0a, 0x0c, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x31, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x12, 0x52, 0x0a, 0x1a, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x17, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, + 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, + 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x22, 0x42, 0x0a, 0x18, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, + 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x22, 0x4e, 0x0a, 0x1c, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x22, 0xdf, 0x01, 0x0a, 0x1d, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, @@ -18696,281 +18696,797 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x51, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x22, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x22, 0x55, 0x0a, 0x23, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x1e, 0x53, 0x65, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x74, 0x0a, 0x1b, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x1e, 0x0a, 0x1c, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xff, 0x02, 0x0a, + 0x19, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x76, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x76, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x12, 0x42, 0x0a, 0x1e, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, + 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x57, 0x69, + 0x74, 0x68, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x1c, + 0x0a, 0x1a, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa0, 0x01, 0x0a, + 0x1e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, + 0x77, 0x0a, 0x1f, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, + 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x12, 0x29, 0x0a, + 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x77, 0x0a, 0x1e, 0x4c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x0a, 0x18, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x1b, 0x0a, 0x19, + 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x05, 0x0a, 0x14, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, + 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, + 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, + 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, + 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, + 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, + 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, + 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, + 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, + 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, + 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, + 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, + 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, + 0x6c, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xe6, 0x01, 0x0a, 0x16, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, + 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, + 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, + 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, + 0x75, 0x6e, 0x22, 0x5b, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, + 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, + 0x85, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, + 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x70, 0x6f, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2c, 0x0a, 0x16, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, + 0x0a, 0x17, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x4d, 0x6f, 0x75, + 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x72, 0x6f, + 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x52, 0x6f, + 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x29, 0x0a, 0x11, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x82, 0x07, 0x0a, 0x17, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, + 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, + 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, + 0x0a, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, + 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, + 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, + 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, + 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, + 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, + 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, + 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, + 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x70, + 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x43, + 0x6f, 0x70, 0x79, 0x12, 0x45, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x18, 0x4d, + 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x48, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, + 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x22, 0x81, 0x02, 0x0a, 0x19, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0x5e, 0x0a, 0x1a, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, + 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd6, 0x03, 0x0a, 0x1b, + 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, - 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, 0x1f, 0x53, 0x65, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x72, 0x0a, 0x1f, - 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, + 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x0d, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x5f, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0c, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, + 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x4c, 0x0a, 0x19, 0x74, 0x6f, 0x6c, 0x65, 0x72, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x74, 0x6f, + 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x63, + 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x65, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x22, 0xba, 0x01, 0x0a, 0x1c, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, + 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x6d, 0x6f, + 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, + 0x65, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, + 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x22, 0x74, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x1e, 0x0a, 0x1c, 0x52, 0x65, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x0a, 0x1a, 0x52, 0x65, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x52, + 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, + 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x52, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x64, 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x1b, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x5f, + 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, + 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, + 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, + 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x22, 0x46, 0x0a, 0x1c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xbc, 0x01, 0x0a, + 0x18, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x77, + 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, + 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x43, 0x0a, 0x19, 0x52, + 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, + 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x22, 0x5b, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, + 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7f, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, + 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, + 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, + 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, + 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, + 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, + 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0x7b, 0x0a, 0x16, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, - 0x22, 0x49, 0x0a, 0x20, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x8e, 0x02, 0x0a, 0x1c, - 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, - 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, - 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x46, 0x0a, 0x1d, - 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x22, 0x6a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x22, 0xd6, 0x04, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, + 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6b, + 0x69, 0x70, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x43, 0x6f, 0x70, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, + 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, + 0x6f, 0x70, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, + 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb8, 0x02, 0x0a, 0x18, + 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x62, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x54, 0x0a, 0x20, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x61, 0x73, 0x12, 0x2d, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, + 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, + 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, + 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, + 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x4d, 0x0a, 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, + 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x51, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x22, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x22, 0x55, 0x0a, 0x23, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x02, + 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x72, 0x0a, 0x1f, 0x53, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x22, + 0x49, 0x0a, 0x20, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x8e, 0x02, 0x0a, 0x1c, 0x53, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, + 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, + 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x46, 0x0a, 0x1d, 0x53, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x22, 0x6a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, + 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x62, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x54, 0x0a, 0x20, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x22, 0xaa, 0x03, 0x0a, 0x21, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, + 0x12, 0x5a, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, 0x0a, 0x18, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4e, 0x0a, + 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8b, 0x01, + 0x0a, 0x1d, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x22, 0xaa, 0x03, 0x0a, 0x21, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, - 0x73, 0x12, 0x5a, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, 0x0a, - 0x18, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4e, - 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8b, - 0x01, 0x0a, 0x1d, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, - 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x20, 0x0a, 0x1e, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, - 0x0a, 0x12, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, - 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, - 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2c, - 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, - 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xf0, 0x01, 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, - 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, - 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, - 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, - 0x61, 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x5e, 0x0a, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x53, 0x0a, 0x17, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x22, 0x1a, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x16, - 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x0a, + 0x12, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2c, 0x0a, + 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x53, + 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xf0, 0x01, 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, + 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x09, + 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x5e, 0x0a, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x53, 0x0a, 0x17, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, + 0x1a, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x16, 0x53, + 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, + 0x19, 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x21, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0xc6, + 0x01, 0x0a, 0x22, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x22, 0x19, 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x21, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, - 0xc6, 0x01, 0x0a, 0x22, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x12, 0x36, 0x0a, 0x0b, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6f, 0x6c, - 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, - 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x36, 0x0a, 0x0b, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6f, 0x6c, 0x64, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, - 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, - 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x65, 0x0a, 0x18, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, - 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, - 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x22, 0x34, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, - 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x69, 0x0a, 0x16, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, - 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0xd8, 0x01, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, + 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, + 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x65, 0x0a, 0x18, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x22, 0x34, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x69, 0x0a, 0x16, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, + 0xfc, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x37, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, + 0x0a, 0x22, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0x25, 0x0a, 0x23, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xf0, 0x01, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x25, 0x0a, @@ -18983,408 +19499,410 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x56, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x88, 0x02, 0x0a, 0x1e, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x73, 0x22, 0x31, 0x0a, 0x15, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x75, 0x64, 0x65, 0x56, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x73, 0x22, 0x88, 0x02, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, + 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, + 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, + 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x31, 0x0a, 0x15, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3c, 0x0a, + 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x8a, 0x02, 0x0a, 0x1f, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x68, 0x0a, 0x10, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4f, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x22, 0x8a, 0x02, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x12, 0x68, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, - 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x4f, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x22, 0x38, 0x0a, 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x16, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, - 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x38, 0x0a, 0x1c, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x22, 0xfa, + 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x12, 0x60, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, + 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x60, 0x0a, 0x10, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, - 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xf9, 0x07, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, - 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x55, - 0x0a, 0x1e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x69, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, - 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x09, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, - 0x5f, 0x6b, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, - 0x4b, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, - 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, - 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, - 0x69, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x12, 0x42, - 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, - 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x12, - 0x77, 0x61, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, - 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x6d, - 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6d, 0x61, 0x78, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, - 0x12, 0x3c, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x6d, - 0x61, 0x78, 0x44, 0x69, 0x66, 0x66, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3c, - 0x0a, 0x1b, 0x72, 0x6f, 0x77, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, - 0x6e, 0x5f, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x15, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x17, 0x72, 0x6f, 0x77, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x6c, 0x75, - 0x6d, 0x6e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x41, 0x74, 0x12, 0x22, 0x0a, 0x0a, - 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, - 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, - 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, - 0x29, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, 0x6b, 0x0a, 0x12, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x92, - 0x01, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x23, - 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, - 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, - 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x90, 0x01, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x23, 0x0a, - 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x73, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xde, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, - 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, - 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x11, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x67, 0x0a, 0x15, + 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, + 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf9, 0x07, 0x0a, 0x12, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, + 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x21, + 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, + 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x55, 0x0a, 0x1e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, + 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x1b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, + 0x0a, 0x09, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x4b, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, + 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, + 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x12, 0x77, 0x61, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, + 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x62, 0x6f, 0x73, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, + 0x6f, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x3c, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, + 0x64, 0x69, 0x66, 0x66, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x44, 0x69, 0x66, 0x66, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x1b, 0x72, 0x6f, 0x77, 0x5f, 0x64, 0x69, + 0x66, 0x66, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, + 0x74, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x72, 0x6f, 0x77, + 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x12, 0x22, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x61, 0x75, 0x74, + 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x29, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, + 0x49, 0x44, 0x22, 0x6b, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, + 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, + 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x56, + 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, + 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0xd7, 0x01, + 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, + 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x90, 0x01, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, + 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xde, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, + 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, + 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x62, + 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, + 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, + 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x64, 0x22, 0x67, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0xe6, 0x07, + 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x0d, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x66, + 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x0e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, + 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, + 0x6f, 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, + 0x74, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, + 0x70, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x61, 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, + 0x66, 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x22, 0xe6, 0x07, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x5f, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x58, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, + 0x1a, 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, - 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x1a, 0xe8, 0x01, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, - 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, - 0x70, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, - 0x74, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, - 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, - 0x77, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, - 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, - 0x12, 0x29, 0x0a, 0x10, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, - 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x30, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, - 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x85, - 0x04, 0x0a, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, - 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, - 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x18, 0x6d, - 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, - 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, - 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, - 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, - 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x85, 0x04, 0x0a, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, - 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x22, 0x90, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, - 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, - 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x0a, - 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4d, 0x69, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x69, - 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, - 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0b, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x37, 0x0a, 0x0c, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, - 0x7f, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, - 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, + 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x18, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, + 0x3c, 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, + 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x07, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, + 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, + 0x75, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, + 0x12, 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x5f, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0xa7, + 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, + 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, - 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, - 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, - 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, - 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, - 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, - 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x2a, 0x42, 0x0a, 0x1c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x65, - 0x64, 0x41, 0x75, 0x74, 0x6f, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, - 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x45, 0x41, 0x56, 0x45, 0x10, - 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, - 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x02, 0x42, 0x28, 0x5a, 0x26, 0x76, 0x69, - 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, - 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, + 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x5b, + 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x16, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, + 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4d, + 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0b, + 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x1c, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, + 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x7f, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, + 0x0a, 0x4d, 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, + 0x11, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, + 0x45, 0x58, 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, + 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, + 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x2a, 0x42, + 0x0a, 0x1c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x65, 0x64, 0x41, 0x75, 0x74, 0x6f, 0x49, 0x6e, 0x63, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x09, + 0x0a, 0x05, 0x4c, 0x45, 0x41, 0x56, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x4d, + 0x4f, 0x56, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, + 0x10, 0x02, 0x42, 0x28, 0x5a, 0x26, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, + 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -19400,7 +19918,7 @@ func file_vtctldata_proto_rawDescGZIP() []byte { } var file_vtctldata_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 301) +var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 309) var file_vtctldata_proto_goTypes = []any{ (MaterializationIntent)(0), // 0: vtctldata.MaterializationIntent (QueryOrdering)(0), // 1: vtctldata.QueryOrdering @@ -19445,557 +19963,567 @@ var file_vtctldata_proto_goTypes = []any{ (*CleanupSchemaMigrationResponse)(nil), // 40: vtctldata.CleanupSchemaMigrationResponse (*CompleteSchemaMigrationRequest)(nil), // 41: vtctldata.CompleteSchemaMigrationRequest (*CompleteSchemaMigrationResponse)(nil), // 42: vtctldata.CompleteSchemaMigrationResponse - (*CreateKeyspaceRequest)(nil), // 43: vtctldata.CreateKeyspaceRequest - (*CreateKeyspaceResponse)(nil), // 44: vtctldata.CreateKeyspaceResponse - (*CreateShardRequest)(nil), // 45: vtctldata.CreateShardRequest - (*CreateShardResponse)(nil), // 46: vtctldata.CreateShardResponse - (*DeleteCellInfoRequest)(nil), // 47: vtctldata.DeleteCellInfoRequest - (*DeleteCellInfoResponse)(nil), // 48: vtctldata.DeleteCellInfoResponse - (*DeleteCellsAliasRequest)(nil), // 49: vtctldata.DeleteCellsAliasRequest - (*DeleteCellsAliasResponse)(nil), // 50: vtctldata.DeleteCellsAliasResponse - (*DeleteKeyspaceRequest)(nil), // 51: vtctldata.DeleteKeyspaceRequest - (*DeleteKeyspaceResponse)(nil), // 52: vtctldata.DeleteKeyspaceResponse - (*DeleteShardsRequest)(nil), // 53: vtctldata.DeleteShardsRequest - (*DeleteShardsResponse)(nil), // 54: vtctldata.DeleteShardsResponse - (*DeleteSrvVSchemaRequest)(nil), // 55: vtctldata.DeleteSrvVSchemaRequest - (*DeleteSrvVSchemaResponse)(nil), // 56: vtctldata.DeleteSrvVSchemaResponse - (*DeleteTabletsRequest)(nil), // 57: vtctldata.DeleteTabletsRequest - (*DeleteTabletsResponse)(nil), // 58: vtctldata.DeleteTabletsResponse - (*EmergencyReparentShardRequest)(nil), // 59: vtctldata.EmergencyReparentShardRequest - (*EmergencyReparentShardResponse)(nil), // 60: vtctldata.EmergencyReparentShardResponse - (*ExecuteFetchAsAppRequest)(nil), // 61: vtctldata.ExecuteFetchAsAppRequest - (*ExecuteFetchAsAppResponse)(nil), // 62: vtctldata.ExecuteFetchAsAppResponse - (*ExecuteFetchAsDBARequest)(nil), // 63: vtctldata.ExecuteFetchAsDBARequest - (*ExecuteFetchAsDBAResponse)(nil), // 64: vtctldata.ExecuteFetchAsDBAResponse - (*ExecuteHookRequest)(nil), // 65: vtctldata.ExecuteHookRequest - (*ExecuteHookResponse)(nil), // 66: vtctldata.ExecuteHookResponse - (*ExecuteMultiFetchAsDBARequest)(nil), // 67: vtctldata.ExecuteMultiFetchAsDBARequest - (*ExecuteMultiFetchAsDBAResponse)(nil), // 68: vtctldata.ExecuteMultiFetchAsDBAResponse - (*FindAllShardsInKeyspaceRequest)(nil), // 69: vtctldata.FindAllShardsInKeyspaceRequest - (*FindAllShardsInKeyspaceResponse)(nil), // 70: vtctldata.FindAllShardsInKeyspaceResponse - (*ForceCutOverSchemaMigrationRequest)(nil), // 71: vtctldata.ForceCutOverSchemaMigrationRequest - (*ForceCutOverSchemaMigrationResponse)(nil), // 72: vtctldata.ForceCutOverSchemaMigrationResponse - (*GetBackupsRequest)(nil), // 73: vtctldata.GetBackupsRequest - (*GetBackupsResponse)(nil), // 74: vtctldata.GetBackupsResponse - (*GetCellInfoRequest)(nil), // 75: vtctldata.GetCellInfoRequest - (*GetCellInfoResponse)(nil), // 76: vtctldata.GetCellInfoResponse - (*GetCellInfoNamesRequest)(nil), // 77: vtctldata.GetCellInfoNamesRequest - (*GetCellInfoNamesResponse)(nil), // 78: vtctldata.GetCellInfoNamesResponse - (*GetCellsAliasesRequest)(nil), // 79: vtctldata.GetCellsAliasesRequest - (*GetCellsAliasesResponse)(nil), // 80: vtctldata.GetCellsAliasesResponse - (*GetFullStatusRequest)(nil), // 81: vtctldata.GetFullStatusRequest - (*GetFullStatusResponse)(nil), // 82: vtctldata.GetFullStatusResponse - (*GetKeyspacesRequest)(nil), // 83: vtctldata.GetKeyspacesRequest - (*GetKeyspacesResponse)(nil), // 84: vtctldata.GetKeyspacesResponse - (*GetKeyspaceRequest)(nil), // 85: vtctldata.GetKeyspaceRequest - (*GetKeyspaceResponse)(nil), // 86: vtctldata.GetKeyspaceResponse - (*GetPermissionsRequest)(nil), // 87: vtctldata.GetPermissionsRequest - (*GetPermissionsResponse)(nil), // 88: vtctldata.GetPermissionsResponse - (*GetKeyspaceRoutingRulesRequest)(nil), // 89: vtctldata.GetKeyspaceRoutingRulesRequest - (*GetKeyspaceRoutingRulesResponse)(nil), // 90: vtctldata.GetKeyspaceRoutingRulesResponse - (*GetRoutingRulesRequest)(nil), // 91: vtctldata.GetRoutingRulesRequest - (*GetRoutingRulesResponse)(nil), // 92: vtctldata.GetRoutingRulesResponse - (*GetSchemaRequest)(nil), // 93: vtctldata.GetSchemaRequest - (*GetSchemaResponse)(nil), // 94: vtctldata.GetSchemaResponse - (*GetSchemaMigrationsRequest)(nil), // 95: vtctldata.GetSchemaMigrationsRequest - (*GetSchemaMigrationsResponse)(nil), // 96: vtctldata.GetSchemaMigrationsResponse - (*GetShardReplicationRequest)(nil), // 97: vtctldata.GetShardReplicationRequest - (*GetShardReplicationResponse)(nil), // 98: vtctldata.GetShardReplicationResponse - (*GetShardRequest)(nil), // 99: vtctldata.GetShardRequest - (*GetShardResponse)(nil), // 100: vtctldata.GetShardResponse - (*GetShardRoutingRulesRequest)(nil), // 101: vtctldata.GetShardRoutingRulesRequest - (*GetShardRoutingRulesResponse)(nil), // 102: vtctldata.GetShardRoutingRulesResponse - (*GetSrvKeyspaceNamesRequest)(nil), // 103: vtctldata.GetSrvKeyspaceNamesRequest - (*GetSrvKeyspaceNamesResponse)(nil), // 104: vtctldata.GetSrvKeyspaceNamesResponse - (*GetSrvKeyspacesRequest)(nil), // 105: vtctldata.GetSrvKeyspacesRequest - (*GetSrvKeyspacesResponse)(nil), // 106: vtctldata.GetSrvKeyspacesResponse - (*UpdateThrottlerConfigRequest)(nil), // 107: vtctldata.UpdateThrottlerConfigRequest - (*UpdateThrottlerConfigResponse)(nil), // 108: vtctldata.UpdateThrottlerConfigResponse - (*GetSrvVSchemaRequest)(nil), // 109: vtctldata.GetSrvVSchemaRequest - (*GetSrvVSchemaResponse)(nil), // 110: vtctldata.GetSrvVSchemaResponse - (*GetSrvVSchemasRequest)(nil), // 111: vtctldata.GetSrvVSchemasRequest - (*GetSrvVSchemasResponse)(nil), // 112: vtctldata.GetSrvVSchemasResponse - (*GetTabletRequest)(nil), // 113: vtctldata.GetTabletRequest - (*GetTabletResponse)(nil), // 114: vtctldata.GetTabletResponse - (*GetTabletsRequest)(nil), // 115: vtctldata.GetTabletsRequest - (*GetTabletsResponse)(nil), // 116: vtctldata.GetTabletsResponse - (*GetThrottlerStatusRequest)(nil), // 117: vtctldata.GetThrottlerStatusRequest - (*GetThrottlerStatusResponse)(nil), // 118: vtctldata.GetThrottlerStatusResponse - (*GetTopologyPathRequest)(nil), // 119: vtctldata.GetTopologyPathRequest - (*GetTopologyPathResponse)(nil), // 120: vtctldata.GetTopologyPathResponse - (*TopologyCell)(nil), // 121: vtctldata.TopologyCell - (*GetUnresolvedTransactionsRequest)(nil), // 122: vtctldata.GetUnresolvedTransactionsRequest - (*GetUnresolvedTransactionsResponse)(nil), // 123: vtctldata.GetUnresolvedTransactionsResponse - (*GetTransactionInfoRequest)(nil), // 124: vtctldata.GetTransactionInfoRequest - (*ShardTransactionState)(nil), // 125: vtctldata.ShardTransactionState - (*GetTransactionInfoResponse)(nil), // 126: vtctldata.GetTransactionInfoResponse - (*ConcludeTransactionRequest)(nil), // 127: vtctldata.ConcludeTransactionRequest - (*ConcludeTransactionResponse)(nil), // 128: vtctldata.ConcludeTransactionResponse - (*GetVSchemaRequest)(nil), // 129: vtctldata.GetVSchemaRequest - (*GetVersionRequest)(nil), // 130: vtctldata.GetVersionRequest - (*GetVersionResponse)(nil), // 131: vtctldata.GetVersionResponse - (*GetVSchemaResponse)(nil), // 132: vtctldata.GetVSchemaResponse - (*GetWorkflowsRequest)(nil), // 133: vtctldata.GetWorkflowsRequest - (*GetWorkflowsResponse)(nil), // 134: vtctldata.GetWorkflowsResponse - (*InitShardPrimaryRequest)(nil), // 135: vtctldata.InitShardPrimaryRequest - (*InitShardPrimaryResponse)(nil), // 136: vtctldata.InitShardPrimaryResponse - (*LaunchSchemaMigrationRequest)(nil), // 137: vtctldata.LaunchSchemaMigrationRequest - (*LaunchSchemaMigrationResponse)(nil), // 138: vtctldata.LaunchSchemaMigrationResponse - (*LookupVindexCreateRequest)(nil), // 139: vtctldata.LookupVindexCreateRequest - (*LookupVindexCreateResponse)(nil), // 140: vtctldata.LookupVindexCreateResponse - (*LookupVindexExternalizeRequest)(nil), // 141: vtctldata.LookupVindexExternalizeRequest - (*LookupVindexExternalizeResponse)(nil), // 142: vtctldata.LookupVindexExternalizeResponse - (*MaterializeCreateRequest)(nil), // 143: vtctldata.MaterializeCreateRequest - (*MaterializeCreateResponse)(nil), // 144: vtctldata.MaterializeCreateResponse - (*MigrateCreateRequest)(nil), // 145: vtctldata.MigrateCreateRequest - (*MigrateCompleteRequest)(nil), // 146: vtctldata.MigrateCompleteRequest - (*MigrateCompleteResponse)(nil), // 147: vtctldata.MigrateCompleteResponse - (*MountRegisterRequest)(nil), // 148: vtctldata.MountRegisterRequest - (*MountRegisterResponse)(nil), // 149: vtctldata.MountRegisterResponse - (*MountUnregisterRequest)(nil), // 150: vtctldata.MountUnregisterRequest - (*MountUnregisterResponse)(nil), // 151: vtctldata.MountUnregisterResponse - (*MountShowRequest)(nil), // 152: vtctldata.MountShowRequest - (*MountShowResponse)(nil), // 153: vtctldata.MountShowResponse - (*MountListRequest)(nil), // 154: vtctldata.MountListRequest - (*MountListResponse)(nil), // 155: vtctldata.MountListResponse - (*MoveTablesCreateRequest)(nil), // 156: vtctldata.MoveTablesCreateRequest - (*MoveTablesCreateResponse)(nil), // 157: vtctldata.MoveTablesCreateResponse - (*MoveTablesCompleteRequest)(nil), // 158: vtctldata.MoveTablesCompleteRequest - (*MoveTablesCompleteResponse)(nil), // 159: vtctldata.MoveTablesCompleteResponse - (*PingTabletRequest)(nil), // 160: vtctldata.PingTabletRequest - (*PingTabletResponse)(nil), // 161: vtctldata.PingTabletResponse - (*PlannedReparentShardRequest)(nil), // 162: vtctldata.PlannedReparentShardRequest - (*PlannedReparentShardResponse)(nil), // 163: vtctldata.PlannedReparentShardResponse - (*RebuildKeyspaceGraphRequest)(nil), // 164: vtctldata.RebuildKeyspaceGraphRequest - (*RebuildKeyspaceGraphResponse)(nil), // 165: vtctldata.RebuildKeyspaceGraphResponse - (*RebuildVSchemaGraphRequest)(nil), // 166: vtctldata.RebuildVSchemaGraphRequest - (*RebuildVSchemaGraphResponse)(nil), // 167: vtctldata.RebuildVSchemaGraphResponse - (*RefreshStateRequest)(nil), // 168: vtctldata.RefreshStateRequest - (*RefreshStateResponse)(nil), // 169: vtctldata.RefreshStateResponse - (*RefreshStateByShardRequest)(nil), // 170: vtctldata.RefreshStateByShardRequest - (*RefreshStateByShardResponse)(nil), // 171: vtctldata.RefreshStateByShardResponse - (*ReloadSchemaRequest)(nil), // 172: vtctldata.ReloadSchemaRequest - (*ReloadSchemaResponse)(nil), // 173: vtctldata.ReloadSchemaResponse - (*ReloadSchemaKeyspaceRequest)(nil), // 174: vtctldata.ReloadSchemaKeyspaceRequest - (*ReloadSchemaKeyspaceResponse)(nil), // 175: vtctldata.ReloadSchemaKeyspaceResponse - (*ReloadSchemaShardRequest)(nil), // 176: vtctldata.ReloadSchemaShardRequest - (*ReloadSchemaShardResponse)(nil), // 177: vtctldata.ReloadSchemaShardResponse - (*RemoveBackupRequest)(nil), // 178: vtctldata.RemoveBackupRequest - (*RemoveBackupResponse)(nil), // 179: vtctldata.RemoveBackupResponse - (*RemoveKeyspaceCellRequest)(nil), // 180: vtctldata.RemoveKeyspaceCellRequest - (*RemoveKeyspaceCellResponse)(nil), // 181: vtctldata.RemoveKeyspaceCellResponse - (*RemoveShardCellRequest)(nil), // 182: vtctldata.RemoveShardCellRequest - (*RemoveShardCellResponse)(nil), // 183: vtctldata.RemoveShardCellResponse - (*ReparentTabletRequest)(nil), // 184: vtctldata.ReparentTabletRequest - (*ReparentTabletResponse)(nil), // 185: vtctldata.ReparentTabletResponse - (*ReshardCreateRequest)(nil), // 186: vtctldata.ReshardCreateRequest - (*RestoreFromBackupRequest)(nil), // 187: vtctldata.RestoreFromBackupRequest - (*RestoreFromBackupResponse)(nil), // 188: vtctldata.RestoreFromBackupResponse - (*RetrySchemaMigrationRequest)(nil), // 189: vtctldata.RetrySchemaMigrationRequest - (*RetrySchemaMigrationResponse)(nil), // 190: vtctldata.RetrySchemaMigrationResponse - (*RunHealthCheckRequest)(nil), // 191: vtctldata.RunHealthCheckRequest - (*RunHealthCheckResponse)(nil), // 192: vtctldata.RunHealthCheckResponse - (*SetKeyspaceDurabilityPolicyRequest)(nil), // 193: vtctldata.SetKeyspaceDurabilityPolicyRequest - (*SetKeyspaceDurabilityPolicyResponse)(nil), // 194: vtctldata.SetKeyspaceDurabilityPolicyResponse - (*SetKeyspaceShardingInfoRequest)(nil), // 195: vtctldata.SetKeyspaceShardingInfoRequest - (*SetKeyspaceShardingInfoResponse)(nil), // 196: vtctldata.SetKeyspaceShardingInfoResponse - (*SetShardIsPrimaryServingRequest)(nil), // 197: vtctldata.SetShardIsPrimaryServingRequest - (*SetShardIsPrimaryServingResponse)(nil), // 198: vtctldata.SetShardIsPrimaryServingResponse - (*SetShardTabletControlRequest)(nil), // 199: vtctldata.SetShardTabletControlRequest - (*SetShardTabletControlResponse)(nil), // 200: vtctldata.SetShardTabletControlResponse - (*SetWritableRequest)(nil), // 201: vtctldata.SetWritableRequest - (*SetWritableResponse)(nil), // 202: vtctldata.SetWritableResponse - (*ShardReplicationAddRequest)(nil), // 203: vtctldata.ShardReplicationAddRequest - (*ShardReplicationAddResponse)(nil), // 204: vtctldata.ShardReplicationAddResponse - (*ShardReplicationFixRequest)(nil), // 205: vtctldata.ShardReplicationFixRequest - (*ShardReplicationFixResponse)(nil), // 206: vtctldata.ShardReplicationFixResponse - (*ShardReplicationPositionsRequest)(nil), // 207: vtctldata.ShardReplicationPositionsRequest - (*ShardReplicationPositionsResponse)(nil), // 208: vtctldata.ShardReplicationPositionsResponse - (*ShardReplicationRemoveRequest)(nil), // 209: vtctldata.ShardReplicationRemoveRequest - (*ShardReplicationRemoveResponse)(nil), // 210: vtctldata.ShardReplicationRemoveResponse - (*SleepTabletRequest)(nil), // 211: vtctldata.SleepTabletRequest - (*SleepTabletResponse)(nil), // 212: vtctldata.SleepTabletResponse - (*SourceShardAddRequest)(nil), // 213: vtctldata.SourceShardAddRequest - (*SourceShardAddResponse)(nil), // 214: vtctldata.SourceShardAddResponse - (*SourceShardDeleteRequest)(nil), // 215: vtctldata.SourceShardDeleteRequest - (*SourceShardDeleteResponse)(nil), // 216: vtctldata.SourceShardDeleteResponse - (*StartReplicationRequest)(nil), // 217: vtctldata.StartReplicationRequest - (*StartReplicationResponse)(nil), // 218: vtctldata.StartReplicationResponse - (*StopReplicationRequest)(nil), // 219: vtctldata.StopReplicationRequest - (*StopReplicationResponse)(nil), // 220: vtctldata.StopReplicationResponse - (*TabletExternallyReparentedRequest)(nil), // 221: vtctldata.TabletExternallyReparentedRequest - (*TabletExternallyReparentedResponse)(nil), // 222: vtctldata.TabletExternallyReparentedResponse - (*UpdateCellInfoRequest)(nil), // 223: vtctldata.UpdateCellInfoRequest - (*UpdateCellInfoResponse)(nil), // 224: vtctldata.UpdateCellInfoResponse - (*UpdateCellsAliasRequest)(nil), // 225: vtctldata.UpdateCellsAliasRequest - (*UpdateCellsAliasResponse)(nil), // 226: vtctldata.UpdateCellsAliasResponse - (*ValidateRequest)(nil), // 227: vtctldata.ValidateRequest - (*ValidateResponse)(nil), // 228: vtctldata.ValidateResponse - (*ValidateKeyspaceRequest)(nil), // 229: vtctldata.ValidateKeyspaceRequest - (*ValidateKeyspaceResponse)(nil), // 230: vtctldata.ValidateKeyspaceResponse - (*ValidateSchemaKeyspaceRequest)(nil), // 231: vtctldata.ValidateSchemaKeyspaceRequest - (*ValidateSchemaKeyspaceResponse)(nil), // 232: vtctldata.ValidateSchemaKeyspaceResponse - (*ValidateShardRequest)(nil), // 233: vtctldata.ValidateShardRequest - (*ValidateShardResponse)(nil), // 234: vtctldata.ValidateShardResponse - (*ValidateVersionKeyspaceRequest)(nil), // 235: vtctldata.ValidateVersionKeyspaceRequest - (*ValidateVersionKeyspaceResponse)(nil), // 236: vtctldata.ValidateVersionKeyspaceResponse - (*ValidateVersionShardRequest)(nil), // 237: vtctldata.ValidateVersionShardRequest - (*ValidateVersionShardResponse)(nil), // 238: vtctldata.ValidateVersionShardResponse - (*ValidateVSchemaRequest)(nil), // 239: vtctldata.ValidateVSchemaRequest - (*ValidateVSchemaResponse)(nil), // 240: vtctldata.ValidateVSchemaResponse - (*VDiffCreateRequest)(nil), // 241: vtctldata.VDiffCreateRequest - (*VDiffCreateResponse)(nil), // 242: vtctldata.VDiffCreateResponse - (*VDiffDeleteRequest)(nil), // 243: vtctldata.VDiffDeleteRequest - (*VDiffDeleteResponse)(nil), // 244: vtctldata.VDiffDeleteResponse - (*VDiffResumeRequest)(nil), // 245: vtctldata.VDiffResumeRequest - (*VDiffResumeResponse)(nil), // 246: vtctldata.VDiffResumeResponse - (*VDiffShowRequest)(nil), // 247: vtctldata.VDiffShowRequest - (*VDiffShowResponse)(nil), // 248: vtctldata.VDiffShowResponse - (*VDiffStopRequest)(nil), // 249: vtctldata.VDiffStopRequest - (*VDiffStopResponse)(nil), // 250: vtctldata.VDiffStopResponse - (*WorkflowDeleteRequest)(nil), // 251: vtctldata.WorkflowDeleteRequest - (*WorkflowDeleteResponse)(nil), // 252: vtctldata.WorkflowDeleteResponse - (*WorkflowStatusRequest)(nil), // 253: vtctldata.WorkflowStatusRequest - (*WorkflowStatusResponse)(nil), // 254: vtctldata.WorkflowStatusResponse - (*WorkflowSwitchTrafficRequest)(nil), // 255: vtctldata.WorkflowSwitchTrafficRequest - (*WorkflowSwitchTrafficResponse)(nil), // 256: vtctldata.WorkflowSwitchTrafficResponse - (*WorkflowUpdateRequest)(nil), // 257: vtctldata.WorkflowUpdateRequest - (*WorkflowUpdateResponse)(nil), // 258: vtctldata.WorkflowUpdateResponse - (*GetMirrorRulesRequest)(nil), // 259: vtctldata.GetMirrorRulesRequest - (*GetMirrorRulesResponse)(nil), // 260: vtctldata.GetMirrorRulesResponse - (*WorkflowMirrorTrafficRequest)(nil), // 261: vtctldata.WorkflowMirrorTrafficRequest - (*WorkflowMirrorTrafficResponse)(nil), // 262: vtctldata.WorkflowMirrorTrafficResponse - nil, // 263: vtctldata.WorkflowOptions.ConfigEntry - nil, // 264: vtctldata.Workflow.ShardStreamsEntry - (*Workflow_ReplicationLocation)(nil), // 265: vtctldata.Workflow.ReplicationLocation - (*Workflow_ShardStream)(nil), // 266: vtctldata.Workflow.ShardStream - (*Workflow_Stream)(nil), // 267: vtctldata.Workflow.Stream - (*Workflow_Stream_CopyState)(nil), // 268: vtctldata.Workflow.Stream.CopyState - (*Workflow_Stream_Log)(nil), // 269: vtctldata.Workflow.Stream.Log - (*Workflow_Stream_ThrottlerStatus)(nil), // 270: vtctldata.Workflow.Stream.ThrottlerStatus - nil, // 271: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - nil, // 272: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry - (*ApplyVSchemaResponse_ParamList)(nil), // 273: vtctldata.ApplyVSchemaResponse.ParamList - nil, // 274: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 275: vtctldata.ChangeTabletTagsRequest.TagsEntry - nil, // 276: vtctldata.ChangeTabletTagsResponse.BeforeTagsEntry - nil, // 277: vtctldata.ChangeTabletTagsResponse.AfterTagsEntry - nil, // 278: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 279: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 280: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - nil, // 281: vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 282: vtctldata.GetCellsAliasesResponse.AliasesEntry - nil, // 283: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry - nil, // 284: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 285: vtctldata.GetSrvKeyspaceNamesResponse.NameList - nil, // 286: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - nil, // 287: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - nil, // 288: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - (*MoveTablesCreateResponse_TabletInfo)(nil), // 289: vtctldata.MoveTablesCreateResponse.TabletInfo - nil, // 290: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 291: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - nil, // 292: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - nil, // 293: vtctldata.ValidateResponse.ResultsByKeyspaceEntry - nil, // 294: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - nil, // 295: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - nil, // 296: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - nil, // 297: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - nil, // 298: vtctldata.VDiffShowResponse.TabletResponsesEntry - (*WorkflowDeleteResponse_TabletInfo)(nil), // 299: vtctldata.WorkflowDeleteResponse.TabletInfo - (*WorkflowStatusResponse_TableCopyState)(nil), // 300: vtctldata.WorkflowStatusResponse.TableCopyState - (*WorkflowStatusResponse_ShardStreamState)(nil), // 301: vtctldata.WorkflowStatusResponse.ShardStreamState - (*WorkflowStatusResponse_ShardStreams)(nil), // 302: vtctldata.WorkflowStatusResponse.ShardStreams - nil, // 303: vtctldata.WorkflowStatusResponse.TableCopyStateEntry - nil, // 304: vtctldata.WorkflowStatusResponse.ShardStreamsEntry - (*WorkflowUpdateResponse_TabletInfo)(nil), // 305: vtctldata.WorkflowUpdateResponse.TabletInfo - (*logutil.Event)(nil), // 306: logutil.Event - (tabletmanagerdata.TabletSelectionPreference)(0), // 307: tabletmanagerdata.TabletSelectionPreference - (*topodata.Keyspace)(nil), // 308: topodata.Keyspace - (*vttime.Time)(nil), // 309: vttime.Time - (*topodata.TabletAlias)(nil), // 310: topodata.TabletAlias - (*vttime.Duration)(nil), // 311: vttime.Duration - (*topodata.Shard)(nil), // 312: topodata.Shard - (*topodata.CellInfo)(nil), // 313: topodata.CellInfo - (*vschema.KeyspaceRoutingRules)(nil), // 314: vschema.KeyspaceRoutingRules - (*vschema.RoutingRules)(nil), // 315: vschema.RoutingRules - (*vschema.ShardRoutingRules)(nil), // 316: vschema.ShardRoutingRules - (*vtrpc.CallerID)(nil), // 317: vtrpc.CallerID - (*vschema.Keyspace)(nil), // 318: vschema.Keyspace - (topodata.TabletType)(0), // 319: topodata.TabletType - (*topodata.Tablet)(nil), // 320: topodata.Tablet - (*tabletmanagerdata.CheckThrottlerResponse)(nil), // 321: tabletmanagerdata.CheckThrottlerResponse - (topodata.KeyspaceType)(0), // 322: topodata.KeyspaceType - (*query.QueryResult)(nil), // 323: query.QueryResult - (*tabletmanagerdata.ExecuteHookRequest)(nil), // 324: tabletmanagerdata.ExecuteHookRequest - (*tabletmanagerdata.ExecuteHookResponse)(nil), // 325: tabletmanagerdata.ExecuteHookResponse - (*mysqlctl.BackupInfo)(nil), // 326: mysqlctl.BackupInfo - (*replicationdata.FullStatus)(nil), // 327: replicationdata.FullStatus - (*tabletmanagerdata.Permissions)(nil), // 328: tabletmanagerdata.Permissions - (*tabletmanagerdata.SchemaDefinition)(nil), // 329: tabletmanagerdata.SchemaDefinition - (*topodata.ThrottledAppRule)(nil), // 330: topodata.ThrottledAppRule - (*vschema.SrvVSchema)(nil), // 331: vschema.SrvVSchema - (*tabletmanagerdata.GetThrottlerStatusResponse)(nil), // 332: tabletmanagerdata.GetThrottlerStatusResponse - (*query.TransactionMetadata)(nil), // 333: query.TransactionMetadata - (*query.Target)(nil), // 334: query.Target - (*topodata.ShardReplicationError)(nil), // 335: topodata.ShardReplicationError - (*topodata.KeyRange)(nil), // 336: topodata.KeyRange - (*topodata.CellsAlias)(nil), // 337: topodata.CellsAlias - (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 338: tabletmanagerdata.UpdateVReplicationWorkflowRequest - (*vschema.MirrorRules)(nil), // 339: vschema.MirrorRules - (*topodata.Shard_TabletControl)(nil), // 340: topodata.Shard.TabletControl - (*binlogdata.BinlogSource)(nil), // 341: binlogdata.BinlogSource - (*topodata.ShardReplication)(nil), // 342: topodata.ShardReplication - (*topodata.SrvKeyspace)(nil), // 343: topodata.SrvKeyspace - (*replicationdata.Status)(nil), // 344: replicationdata.Status - (*tabletmanagerdata.VDiffResponse)(nil), // 345: tabletmanagerdata.VDiffResponse + (*CopySchemaShardRequest)(nil), // 43: vtctldata.CopySchemaShardRequest + (*CopySchemaShardResponse)(nil), // 44: vtctldata.CopySchemaShardResponse + (*CreateKeyspaceRequest)(nil), // 45: vtctldata.CreateKeyspaceRequest + (*CreateKeyspaceResponse)(nil), // 46: vtctldata.CreateKeyspaceResponse + (*CreateShardRequest)(nil), // 47: vtctldata.CreateShardRequest + (*CreateShardResponse)(nil), // 48: vtctldata.CreateShardResponse + (*DeleteCellInfoRequest)(nil), // 49: vtctldata.DeleteCellInfoRequest + (*DeleteCellInfoResponse)(nil), // 50: vtctldata.DeleteCellInfoResponse + (*DeleteCellsAliasRequest)(nil), // 51: vtctldata.DeleteCellsAliasRequest + (*DeleteCellsAliasResponse)(nil), // 52: vtctldata.DeleteCellsAliasResponse + (*DeleteKeyspaceRequest)(nil), // 53: vtctldata.DeleteKeyspaceRequest + (*DeleteKeyspaceResponse)(nil), // 54: vtctldata.DeleteKeyspaceResponse + (*DeleteShardsRequest)(nil), // 55: vtctldata.DeleteShardsRequest + (*DeleteShardsResponse)(nil), // 56: vtctldata.DeleteShardsResponse + (*DeleteSrvVSchemaRequest)(nil), // 57: vtctldata.DeleteSrvVSchemaRequest + (*DeleteSrvVSchemaResponse)(nil), // 58: vtctldata.DeleteSrvVSchemaResponse + (*DeleteTabletsRequest)(nil), // 59: vtctldata.DeleteTabletsRequest + (*DeleteTabletsResponse)(nil), // 60: vtctldata.DeleteTabletsResponse + (*EmergencyReparentShardRequest)(nil), // 61: vtctldata.EmergencyReparentShardRequest + (*EmergencyReparentShardResponse)(nil), // 62: vtctldata.EmergencyReparentShardResponse + (*ExecuteFetchAsAppRequest)(nil), // 63: vtctldata.ExecuteFetchAsAppRequest + (*ExecuteFetchAsAppResponse)(nil), // 64: vtctldata.ExecuteFetchAsAppResponse + (*ExecuteFetchAsDBARequest)(nil), // 65: vtctldata.ExecuteFetchAsDBARequest + (*ExecuteFetchAsDBAResponse)(nil), // 66: vtctldata.ExecuteFetchAsDBAResponse + (*ExecuteHookRequest)(nil), // 67: vtctldata.ExecuteHookRequest + (*ExecuteHookResponse)(nil), // 68: vtctldata.ExecuteHookResponse + (*ExecuteMultiFetchAsDBARequest)(nil), // 69: vtctldata.ExecuteMultiFetchAsDBARequest + (*ExecuteMultiFetchAsDBAResponse)(nil), // 70: vtctldata.ExecuteMultiFetchAsDBAResponse + (*FindAllShardsInKeyspaceRequest)(nil), // 71: vtctldata.FindAllShardsInKeyspaceRequest + (*FindAllShardsInKeyspaceResponse)(nil), // 72: vtctldata.FindAllShardsInKeyspaceResponse + (*ForceCutOverSchemaMigrationRequest)(nil), // 73: vtctldata.ForceCutOverSchemaMigrationRequest + (*ForceCutOverSchemaMigrationResponse)(nil), // 74: vtctldata.ForceCutOverSchemaMigrationResponse + (*GetBackupsRequest)(nil), // 75: vtctldata.GetBackupsRequest + (*GetBackupsResponse)(nil), // 76: vtctldata.GetBackupsResponse + (*GetCellInfoRequest)(nil), // 77: vtctldata.GetCellInfoRequest + (*GetCellInfoResponse)(nil), // 78: vtctldata.GetCellInfoResponse + (*GetCellInfoNamesRequest)(nil), // 79: vtctldata.GetCellInfoNamesRequest + (*GetCellInfoNamesResponse)(nil), // 80: vtctldata.GetCellInfoNamesResponse + (*GetCellsAliasesRequest)(nil), // 81: vtctldata.GetCellsAliasesRequest + (*GetCellsAliasesResponse)(nil), // 82: vtctldata.GetCellsAliasesResponse + (*GetFullStatusRequest)(nil), // 83: vtctldata.GetFullStatusRequest + (*GetFullStatusResponse)(nil), // 84: vtctldata.GetFullStatusResponse + (*GetKeyspacesRequest)(nil), // 85: vtctldata.GetKeyspacesRequest + (*GetKeyspacesResponse)(nil), // 86: vtctldata.GetKeyspacesResponse + (*GetKeyspaceRequest)(nil), // 87: vtctldata.GetKeyspaceRequest + (*GetKeyspaceResponse)(nil), // 88: vtctldata.GetKeyspaceResponse + (*GetPermissionsRequest)(nil), // 89: vtctldata.GetPermissionsRequest + (*GetPermissionsResponse)(nil), // 90: vtctldata.GetPermissionsResponse + (*GetKeyspaceRoutingRulesRequest)(nil), // 91: vtctldata.GetKeyspaceRoutingRulesRequest + (*GetKeyspaceRoutingRulesResponse)(nil), // 92: vtctldata.GetKeyspaceRoutingRulesResponse + (*GetRoutingRulesRequest)(nil), // 93: vtctldata.GetRoutingRulesRequest + (*GetRoutingRulesResponse)(nil), // 94: vtctldata.GetRoutingRulesResponse + (*GetSchemaRequest)(nil), // 95: vtctldata.GetSchemaRequest + (*GetSchemaResponse)(nil), // 96: vtctldata.GetSchemaResponse + (*GetSchemaMigrationsRequest)(nil), // 97: vtctldata.GetSchemaMigrationsRequest + (*GetSchemaMigrationsResponse)(nil), // 98: vtctldata.GetSchemaMigrationsResponse + (*GetShardReplicationRequest)(nil), // 99: vtctldata.GetShardReplicationRequest + (*GetShardReplicationResponse)(nil), // 100: vtctldata.GetShardReplicationResponse + (*GetShardRequest)(nil), // 101: vtctldata.GetShardRequest + (*GetShardResponse)(nil), // 102: vtctldata.GetShardResponse + (*GetShardRoutingRulesRequest)(nil), // 103: vtctldata.GetShardRoutingRulesRequest + (*GetShardRoutingRulesResponse)(nil), // 104: vtctldata.GetShardRoutingRulesResponse + (*GetSrvKeyspaceNamesRequest)(nil), // 105: vtctldata.GetSrvKeyspaceNamesRequest + (*GetSrvKeyspaceNamesResponse)(nil), // 106: vtctldata.GetSrvKeyspaceNamesResponse + (*GetSrvKeyspacesRequest)(nil), // 107: vtctldata.GetSrvKeyspacesRequest + (*GetSrvKeyspacesResponse)(nil), // 108: vtctldata.GetSrvKeyspacesResponse + (*UpdateThrottlerConfigRequest)(nil), // 109: vtctldata.UpdateThrottlerConfigRequest + (*UpdateThrottlerConfigResponse)(nil), // 110: vtctldata.UpdateThrottlerConfigResponse + (*GetSrvVSchemaRequest)(nil), // 111: vtctldata.GetSrvVSchemaRequest + (*GetSrvVSchemaResponse)(nil), // 112: vtctldata.GetSrvVSchemaResponse + (*GetSrvVSchemasRequest)(nil), // 113: vtctldata.GetSrvVSchemasRequest + (*GetSrvVSchemasResponse)(nil), // 114: vtctldata.GetSrvVSchemasResponse + (*GetTabletRequest)(nil), // 115: vtctldata.GetTabletRequest + (*GetTabletResponse)(nil), // 116: vtctldata.GetTabletResponse + (*GetTabletsRequest)(nil), // 117: vtctldata.GetTabletsRequest + (*GetTabletsResponse)(nil), // 118: vtctldata.GetTabletsResponse + (*GetThrottlerStatusRequest)(nil), // 119: vtctldata.GetThrottlerStatusRequest + (*GetThrottlerStatusResponse)(nil), // 120: vtctldata.GetThrottlerStatusResponse + (*GetTopologyPathRequest)(nil), // 121: vtctldata.GetTopologyPathRequest + (*GetTopologyPathResponse)(nil), // 122: vtctldata.GetTopologyPathResponse + (*TopologyCell)(nil), // 123: vtctldata.TopologyCell + (*GetUnresolvedTransactionsRequest)(nil), // 124: vtctldata.GetUnresolvedTransactionsRequest + (*GetUnresolvedTransactionsResponse)(nil), // 125: vtctldata.GetUnresolvedTransactionsResponse + (*GetTransactionInfoRequest)(nil), // 126: vtctldata.GetTransactionInfoRequest + (*ShardTransactionState)(nil), // 127: vtctldata.ShardTransactionState + (*GetTransactionInfoResponse)(nil), // 128: vtctldata.GetTransactionInfoResponse + (*ConcludeTransactionRequest)(nil), // 129: vtctldata.ConcludeTransactionRequest + (*ConcludeTransactionResponse)(nil), // 130: vtctldata.ConcludeTransactionResponse + (*GetVSchemaRequest)(nil), // 131: vtctldata.GetVSchemaRequest + (*GetVersionRequest)(nil), // 132: vtctldata.GetVersionRequest + (*GetVersionResponse)(nil), // 133: vtctldata.GetVersionResponse + (*GetVSchemaResponse)(nil), // 134: vtctldata.GetVSchemaResponse + (*GetWorkflowsRequest)(nil), // 135: vtctldata.GetWorkflowsRequest + (*GetWorkflowsResponse)(nil), // 136: vtctldata.GetWorkflowsResponse + (*InitShardPrimaryRequest)(nil), // 137: vtctldata.InitShardPrimaryRequest + (*InitShardPrimaryResponse)(nil), // 138: vtctldata.InitShardPrimaryResponse + (*LaunchSchemaMigrationRequest)(nil), // 139: vtctldata.LaunchSchemaMigrationRequest + (*LaunchSchemaMigrationResponse)(nil), // 140: vtctldata.LaunchSchemaMigrationResponse + (*LookupVindexCompleteRequest)(nil), // 141: vtctldata.LookupVindexCompleteRequest + (*LookupVindexCompleteResponse)(nil), // 142: vtctldata.LookupVindexCompleteResponse + (*LookupVindexCreateRequest)(nil), // 143: vtctldata.LookupVindexCreateRequest + (*LookupVindexCreateResponse)(nil), // 144: vtctldata.LookupVindexCreateResponse + (*LookupVindexExternalizeRequest)(nil), // 145: vtctldata.LookupVindexExternalizeRequest + (*LookupVindexExternalizeResponse)(nil), // 146: vtctldata.LookupVindexExternalizeResponse + (*LookupVindexInternalizeRequest)(nil), // 147: vtctldata.LookupVindexInternalizeRequest + (*LookupVindexInternalizeResponse)(nil), // 148: vtctldata.LookupVindexInternalizeResponse + (*MaterializeCreateRequest)(nil), // 149: vtctldata.MaterializeCreateRequest + (*MaterializeCreateResponse)(nil), // 150: vtctldata.MaterializeCreateResponse + (*MigrateCreateRequest)(nil), // 151: vtctldata.MigrateCreateRequest + (*MigrateCompleteRequest)(nil), // 152: vtctldata.MigrateCompleteRequest + (*MigrateCompleteResponse)(nil), // 153: vtctldata.MigrateCompleteResponse + (*MountRegisterRequest)(nil), // 154: vtctldata.MountRegisterRequest + (*MountRegisterResponse)(nil), // 155: vtctldata.MountRegisterResponse + (*MountUnregisterRequest)(nil), // 156: vtctldata.MountUnregisterRequest + (*MountUnregisterResponse)(nil), // 157: vtctldata.MountUnregisterResponse + (*MountShowRequest)(nil), // 158: vtctldata.MountShowRequest + (*MountShowResponse)(nil), // 159: vtctldata.MountShowResponse + (*MountListRequest)(nil), // 160: vtctldata.MountListRequest + (*MountListResponse)(nil), // 161: vtctldata.MountListResponse + (*MoveTablesCreateRequest)(nil), // 162: vtctldata.MoveTablesCreateRequest + (*MoveTablesCreateResponse)(nil), // 163: vtctldata.MoveTablesCreateResponse + (*MoveTablesCompleteRequest)(nil), // 164: vtctldata.MoveTablesCompleteRequest + (*MoveTablesCompleteResponse)(nil), // 165: vtctldata.MoveTablesCompleteResponse + (*PingTabletRequest)(nil), // 166: vtctldata.PingTabletRequest + (*PingTabletResponse)(nil), // 167: vtctldata.PingTabletResponse + (*PlannedReparentShardRequest)(nil), // 168: vtctldata.PlannedReparentShardRequest + (*PlannedReparentShardResponse)(nil), // 169: vtctldata.PlannedReparentShardResponse + (*RebuildKeyspaceGraphRequest)(nil), // 170: vtctldata.RebuildKeyspaceGraphRequest + (*RebuildKeyspaceGraphResponse)(nil), // 171: vtctldata.RebuildKeyspaceGraphResponse + (*RebuildVSchemaGraphRequest)(nil), // 172: vtctldata.RebuildVSchemaGraphRequest + (*RebuildVSchemaGraphResponse)(nil), // 173: vtctldata.RebuildVSchemaGraphResponse + (*RefreshStateRequest)(nil), // 174: vtctldata.RefreshStateRequest + (*RefreshStateResponse)(nil), // 175: vtctldata.RefreshStateResponse + (*RefreshStateByShardRequest)(nil), // 176: vtctldata.RefreshStateByShardRequest + (*RefreshStateByShardResponse)(nil), // 177: vtctldata.RefreshStateByShardResponse + (*ReloadSchemaRequest)(nil), // 178: vtctldata.ReloadSchemaRequest + (*ReloadSchemaResponse)(nil), // 179: vtctldata.ReloadSchemaResponse + (*ReloadSchemaKeyspaceRequest)(nil), // 180: vtctldata.ReloadSchemaKeyspaceRequest + (*ReloadSchemaKeyspaceResponse)(nil), // 181: vtctldata.ReloadSchemaKeyspaceResponse + (*ReloadSchemaShardRequest)(nil), // 182: vtctldata.ReloadSchemaShardRequest + (*ReloadSchemaShardResponse)(nil), // 183: vtctldata.ReloadSchemaShardResponse + (*RemoveBackupRequest)(nil), // 184: vtctldata.RemoveBackupRequest + (*RemoveBackupResponse)(nil), // 185: vtctldata.RemoveBackupResponse + (*RemoveKeyspaceCellRequest)(nil), // 186: vtctldata.RemoveKeyspaceCellRequest + (*RemoveKeyspaceCellResponse)(nil), // 187: vtctldata.RemoveKeyspaceCellResponse + (*RemoveShardCellRequest)(nil), // 188: vtctldata.RemoveShardCellRequest + (*RemoveShardCellResponse)(nil), // 189: vtctldata.RemoveShardCellResponse + (*ReparentTabletRequest)(nil), // 190: vtctldata.ReparentTabletRequest + (*ReparentTabletResponse)(nil), // 191: vtctldata.ReparentTabletResponse + (*ReshardCreateRequest)(nil), // 192: vtctldata.ReshardCreateRequest + (*RestoreFromBackupRequest)(nil), // 193: vtctldata.RestoreFromBackupRequest + (*RestoreFromBackupResponse)(nil), // 194: vtctldata.RestoreFromBackupResponse + (*RetrySchemaMigrationRequest)(nil), // 195: vtctldata.RetrySchemaMigrationRequest + (*RetrySchemaMigrationResponse)(nil), // 196: vtctldata.RetrySchemaMigrationResponse + (*RunHealthCheckRequest)(nil), // 197: vtctldata.RunHealthCheckRequest + (*RunHealthCheckResponse)(nil), // 198: vtctldata.RunHealthCheckResponse + (*SetKeyspaceDurabilityPolicyRequest)(nil), // 199: vtctldata.SetKeyspaceDurabilityPolicyRequest + (*SetKeyspaceDurabilityPolicyResponse)(nil), // 200: vtctldata.SetKeyspaceDurabilityPolicyResponse + (*SetKeyspaceShardingInfoRequest)(nil), // 201: vtctldata.SetKeyspaceShardingInfoRequest + (*SetKeyspaceShardingInfoResponse)(nil), // 202: vtctldata.SetKeyspaceShardingInfoResponse + (*SetShardIsPrimaryServingRequest)(nil), // 203: vtctldata.SetShardIsPrimaryServingRequest + (*SetShardIsPrimaryServingResponse)(nil), // 204: vtctldata.SetShardIsPrimaryServingResponse + (*SetShardTabletControlRequest)(nil), // 205: vtctldata.SetShardTabletControlRequest + (*SetShardTabletControlResponse)(nil), // 206: vtctldata.SetShardTabletControlResponse + (*SetWritableRequest)(nil), // 207: vtctldata.SetWritableRequest + (*SetWritableResponse)(nil), // 208: vtctldata.SetWritableResponse + (*ShardReplicationAddRequest)(nil), // 209: vtctldata.ShardReplicationAddRequest + (*ShardReplicationAddResponse)(nil), // 210: vtctldata.ShardReplicationAddResponse + (*ShardReplicationFixRequest)(nil), // 211: vtctldata.ShardReplicationFixRequest + (*ShardReplicationFixResponse)(nil), // 212: vtctldata.ShardReplicationFixResponse + (*ShardReplicationPositionsRequest)(nil), // 213: vtctldata.ShardReplicationPositionsRequest + (*ShardReplicationPositionsResponse)(nil), // 214: vtctldata.ShardReplicationPositionsResponse + (*ShardReplicationRemoveRequest)(nil), // 215: vtctldata.ShardReplicationRemoveRequest + (*ShardReplicationRemoveResponse)(nil), // 216: vtctldata.ShardReplicationRemoveResponse + (*SleepTabletRequest)(nil), // 217: vtctldata.SleepTabletRequest + (*SleepTabletResponse)(nil), // 218: vtctldata.SleepTabletResponse + (*SourceShardAddRequest)(nil), // 219: vtctldata.SourceShardAddRequest + (*SourceShardAddResponse)(nil), // 220: vtctldata.SourceShardAddResponse + (*SourceShardDeleteRequest)(nil), // 221: vtctldata.SourceShardDeleteRequest + (*SourceShardDeleteResponse)(nil), // 222: vtctldata.SourceShardDeleteResponse + (*StartReplicationRequest)(nil), // 223: vtctldata.StartReplicationRequest + (*StartReplicationResponse)(nil), // 224: vtctldata.StartReplicationResponse + (*StopReplicationRequest)(nil), // 225: vtctldata.StopReplicationRequest + (*StopReplicationResponse)(nil), // 226: vtctldata.StopReplicationResponse + (*TabletExternallyReparentedRequest)(nil), // 227: vtctldata.TabletExternallyReparentedRequest + (*TabletExternallyReparentedResponse)(nil), // 228: vtctldata.TabletExternallyReparentedResponse + (*UpdateCellInfoRequest)(nil), // 229: vtctldata.UpdateCellInfoRequest + (*UpdateCellInfoResponse)(nil), // 230: vtctldata.UpdateCellInfoResponse + (*UpdateCellsAliasRequest)(nil), // 231: vtctldata.UpdateCellsAliasRequest + (*UpdateCellsAliasResponse)(nil), // 232: vtctldata.UpdateCellsAliasResponse + (*ValidateRequest)(nil), // 233: vtctldata.ValidateRequest + (*ValidateResponse)(nil), // 234: vtctldata.ValidateResponse + (*ValidateKeyspaceRequest)(nil), // 235: vtctldata.ValidateKeyspaceRequest + (*ValidateKeyspaceResponse)(nil), // 236: vtctldata.ValidateKeyspaceResponse + (*ValidatePermissionsKeyspaceRequest)(nil), // 237: vtctldata.ValidatePermissionsKeyspaceRequest + (*ValidatePermissionsKeyspaceResponse)(nil), // 238: vtctldata.ValidatePermissionsKeyspaceResponse + (*ValidateSchemaKeyspaceRequest)(nil), // 239: vtctldata.ValidateSchemaKeyspaceRequest + (*ValidateSchemaKeyspaceResponse)(nil), // 240: vtctldata.ValidateSchemaKeyspaceResponse + (*ValidateShardRequest)(nil), // 241: vtctldata.ValidateShardRequest + (*ValidateShardResponse)(nil), // 242: vtctldata.ValidateShardResponse + (*ValidateVersionKeyspaceRequest)(nil), // 243: vtctldata.ValidateVersionKeyspaceRequest + (*ValidateVersionKeyspaceResponse)(nil), // 244: vtctldata.ValidateVersionKeyspaceResponse + (*ValidateVersionShardRequest)(nil), // 245: vtctldata.ValidateVersionShardRequest + (*ValidateVersionShardResponse)(nil), // 246: vtctldata.ValidateVersionShardResponse + (*ValidateVSchemaRequest)(nil), // 247: vtctldata.ValidateVSchemaRequest + (*ValidateVSchemaResponse)(nil), // 248: vtctldata.ValidateVSchemaResponse + (*VDiffCreateRequest)(nil), // 249: vtctldata.VDiffCreateRequest + (*VDiffCreateResponse)(nil), // 250: vtctldata.VDiffCreateResponse + (*VDiffDeleteRequest)(nil), // 251: vtctldata.VDiffDeleteRequest + (*VDiffDeleteResponse)(nil), // 252: vtctldata.VDiffDeleteResponse + (*VDiffResumeRequest)(nil), // 253: vtctldata.VDiffResumeRequest + (*VDiffResumeResponse)(nil), // 254: vtctldata.VDiffResumeResponse + (*VDiffShowRequest)(nil), // 255: vtctldata.VDiffShowRequest + (*VDiffShowResponse)(nil), // 256: vtctldata.VDiffShowResponse + (*VDiffStopRequest)(nil), // 257: vtctldata.VDiffStopRequest + (*VDiffStopResponse)(nil), // 258: vtctldata.VDiffStopResponse + (*WorkflowDeleteRequest)(nil), // 259: vtctldata.WorkflowDeleteRequest + (*WorkflowDeleteResponse)(nil), // 260: vtctldata.WorkflowDeleteResponse + (*WorkflowStatusRequest)(nil), // 261: vtctldata.WorkflowStatusRequest + (*WorkflowStatusResponse)(nil), // 262: vtctldata.WorkflowStatusResponse + (*WorkflowSwitchTrafficRequest)(nil), // 263: vtctldata.WorkflowSwitchTrafficRequest + (*WorkflowSwitchTrafficResponse)(nil), // 264: vtctldata.WorkflowSwitchTrafficResponse + (*WorkflowUpdateRequest)(nil), // 265: vtctldata.WorkflowUpdateRequest + (*WorkflowUpdateResponse)(nil), // 266: vtctldata.WorkflowUpdateResponse + (*GetMirrorRulesRequest)(nil), // 267: vtctldata.GetMirrorRulesRequest + (*GetMirrorRulesResponse)(nil), // 268: vtctldata.GetMirrorRulesResponse + (*WorkflowMirrorTrafficRequest)(nil), // 269: vtctldata.WorkflowMirrorTrafficRequest + (*WorkflowMirrorTrafficResponse)(nil), // 270: vtctldata.WorkflowMirrorTrafficResponse + nil, // 271: vtctldata.WorkflowOptions.ConfigEntry + nil, // 272: vtctldata.Workflow.ShardStreamsEntry + (*Workflow_ReplicationLocation)(nil), // 273: vtctldata.Workflow.ReplicationLocation + (*Workflow_ShardStream)(nil), // 274: vtctldata.Workflow.ShardStream + (*Workflow_Stream)(nil), // 275: vtctldata.Workflow.Stream + (*Workflow_Stream_CopyState)(nil), // 276: vtctldata.Workflow.Stream.CopyState + (*Workflow_Stream_Log)(nil), // 277: vtctldata.Workflow.Stream.Log + (*Workflow_Stream_ThrottlerStatus)(nil), // 278: vtctldata.Workflow.Stream.ThrottlerStatus + nil, // 279: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + nil, // 280: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry + (*ApplyVSchemaResponse_ParamList)(nil), // 281: vtctldata.ApplyVSchemaResponse.ParamList + nil, // 282: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 283: vtctldata.ChangeTabletTagsRequest.TagsEntry + nil, // 284: vtctldata.ChangeTabletTagsResponse.BeforeTagsEntry + nil, // 285: vtctldata.ChangeTabletTagsResponse.AfterTagsEntry + nil, // 286: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 287: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 288: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + nil, // 289: vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 290: vtctldata.GetCellsAliasesResponse.AliasesEntry + nil, // 291: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry + nil, // 292: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 293: vtctldata.GetSrvKeyspaceNamesResponse.NameList + nil, // 294: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + nil, // 295: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + nil, // 296: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + (*MoveTablesCreateResponse_TabletInfo)(nil), // 297: vtctldata.MoveTablesCreateResponse.TabletInfo + nil, // 298: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 299: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + nil, // 300: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + nil, // 301: vtctldata.ValidateResponse.ResultsByKeyspaceEntry + nil, // 302: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + nil, // 303: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + nil, // 304: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + nil, // 305: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + nil, // 306: vtctldata.VDiffShowResponse.TabletResponsesEntry + (*WorkflowDeleteResponse_TabletInfo)(nil), // 307: vtctldata.WorkflowDeleteResponse.TabletInfo + (*WorkflowStatusResponse_TableCopyState)(nil), // 308: vtctldata.WorkflowStatusResponse.TableCopyState + (*WorkflowStatusResponse_ShardStreamState)(nil), // 309: vtctldata.WorkflowStatusResponse.ShardStreamState + (*WorkflowStatusResponse_ShardStreams)(nil), // 310: vtctldata.WorkflowStatusResponse.ShardStreams + nil, // 311: vtctldata.WorkflowStatusResponse.TableCopyStateEntry + nil, // 312: vtctldata.WorkflowStatusResponse.ShardStreamsEntry + (*WorkflowUpdateResponse_TabletInfo)(nil), // 313: vtctldata.WorkflowUpdateResponse.TabletInfo + (*logutil.Event)(nil), // 314: logutil.Event + (tabletmanagerdata.TabletSelectionPreference)(0), // 315: tabletmanagerdata.TabletSelectionPreference + (*topodata.Keyspace)(nil), // 316: topodata.Keyspace + (*vttime.Time)(nil), // 317: vttime.Time + (*topodata.TabletAlias)(nil), // 318: topodata.TabletAlias + (*vttime.Duration)(nil), // 319: vttime.Duration + (*topodata.Shard)(nil), // 320: topodata.Shard + (*topodata.CellInfo)(nil), // 321: topodata.CellInfo + (*vschema.KeyspaceRoutingRules)(nil), // 322: vschema.KeyspaceRoutingRules + (*vschema.RoutingRules)(nil), // 323: vschema.RoutingRules + (*vschema.ShardRoutingRules)(nil), // 324: vschema.ShardRoutingRules + (*vtrpc.CallerID)(nil), // 325: vtrpc.CallerID + (*vschema.Keyspace)(nil), // 326: vschema.Keyspace + (topodata.TabletType)(0), // 327: topodata.TabletType + (*topodata.Tablet)(nil), // 328: topodata.Tablet + (*tabletmanagerdata.CheckThrottlerResponse)(nil), // 329: tabletmanagerdata.CheckThrottlerResponse + (topodata.KeyspaceType)(0), // 330: topodata.KeyspaceType + (*query.QueryResult)(nil), // 331: query.QueryResult + (*tabletmanagerdata.ExecuteHookRequest)(nil), // 332: tabletmanagerdata.ExecuteHookRequest + (*tabletmanagerdata.ExecuteHookResponse)(nil), // 333: tabletmanagerdata.ExecuteHookResponse + (*mysqlctl.BackupInfo)(nil), // 334: mysqlctl.BackupInfo + (*replicationdata.FullStatus)(nil), // 335: replicationdata.FullStatus + (*tabletmanagerdata.Permissions)(nil), // 336: tabletmanagerdata.Permissions + (*tabletmanagerdata.SchemaDefinition)(nil), // 337: tabletmanagerdata.SchemaDefinition + (*topodata.ThrottledAppRule)(nil), // 338: topodata.ThrottledAppRule + (*vschema.SrvVSchema)(nil), // 339: vschema.SrvVSchema + (*tabletmanagerdata.GetThrottlerStatusResponse)(nil), // 340: tabletmanagerdata.GetThrottlerStatusResponse + (*query.TransactionMetadata)(nil), // 341: query.TransactionMetadata + (*query.Target)(nil), // 342: query.Target + (*topodata.ShardReplicationError)(nil), // 343: topodata.ShardReplicationError + (*topodata.KeyRange)(nil), // 344: topodata.KeyRange + (*topodata.CellsAlias)(nil), // 345: topodata.CellsAlias + (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 346: tabletmanagerdata.UpdateVReplicationWorkflowRequest + (*vschema.MirrorRules)(nil), // 347: vschema.MirrorRules + (*topodata.Shard_TabletControl)(nil), // 348: topodata.Shard.TabletControl + (*binlogdata.BinlogSource)(nil), // 349: binlogdata.BinlogSource + (*topodata.ShardReplication)(nil), // 350: topodata.ShardReplication + (*topodata.SrvKeyspace)(nil), // 351: topodata.SrvKeyspace + (*replicationdata.Status)(nil), // 352: replicationdata.Status + (*tabletmanagerdata.VDiffResponse)(nil), // 353: tabletmanagerdata.VDiffResponse } var file_vtctldata_proto_depIdxs = []int32{ - 306, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event + 314, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event 7, // 1: vtctldata.MaterializeSettings.table_settings:type_name -> vtctldata.TableMaterializeSettings 0, // 2: vtctldata.MaterializeSettings.materialization_intent:type_name -> vtctldata.MaterializationIntent - 307, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 315, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference 12, // 4: vtctldata.MaterializeSettings.workflow_options:type_name -> vtctldata.WorkflowOptions - 308, // 5: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace + 316, // 5: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace 3, // 6: vtctldata.SchemaMigration.strategy:type_name -> vtctldata.SchemaMigration.Strategy - 309, // 7: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time - 309, // 8: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time - 309, // 9: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time - 309, // 10: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time - 309, // 11: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time - 309, // 12: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time - 309, // 13: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time + 317, // 7: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time + 317, // 8: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time + 317, // 9: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time + 317, // 10: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time + 317, // 11: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time + 317, // 12: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time + 317, // 13: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time 4, // 14: vtctldata.SchemaMigration.status:type_name -> vtctldata.SchemaMigration.Status - 310, // 15: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias - 311, // 16: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration - 309, // 17: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time - 309, // 18: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time - 309, // 19: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time - 309, // 20: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time - 312, // 21: vtctldata.Shard.shard:type_name -> topodata.Shard + 318, // 15: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias + 319, // 16: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration + 317, // 17: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time + 317, // 18: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time + 317, // 19: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time + 317, // 20: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time + 320, // 21: vtctldata.Shard.shard:type_name -> topodata.Shard 2, // 22: vtctldata.WorkflowOptions.sharded_auto_increment_handling:type_name -> vtctldata.ShardedAutoIncrementHandling - 263, // 23: vtctldata.WorkflowOptions.config:type_name -> vtctldata.WorkflowOptions.ConfigEntry - 265, // 24: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation - 265, // 25: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation - 264, // 26: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry + 271, // 23: vtctldata.WorkflowOptions.config:type_name -> vtctldata.WorkflowOptions.ConfigEntry + 273, // 24: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation + 273, // 25: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation + 272, // 26: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry 12, // 27: vtctldata.Workflow.options:type_name -> vtctldata.WorkflowOptions - 313, // 28: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 314, // 29: vtctldata.ApplyKeyspaceRoutingRulesRequest.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 314, // 30: vtctldata.ApplyKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 315, // 31: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules - 316, // 32: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 311, // 33: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration - 317, // 34: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID - 271, // 35: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - 318, // 36: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace - 318, // 37: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 272, // 38: vtctldata.ApplyVSchemaResponse.unknown_vindex_params:type_name -> vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry - 310, // 39: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 40: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 306, // 41: vtctldata.BackupResponse.event:type_name -> logutil.Event - 274, // 42: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - 310, // 43: vtctldata.ChangeTabletTagsRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 44: vtctldata.ChangeTabletTagsRequest.tags:type_name -> vtctldata.ChangeTabletTagsRequest.TagsEntry - 276, // 45: vtctldata.ChangeTabletTagsResponse.before_tags:type_name -> vtctldata.ChangeTabletTagsResponse.BeforeTagsEntry - 277, // 46: vtctldata.ChangeTabletTagsResponse.after_tags:type_name -> vtctldata.ChangeTabletTagsResponse.AfterTagsEntry - 310, // 47: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias - 319, // 48: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType - 320, // 49: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet - 320, // 50: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet - 310, // 51: vtctldata.CheckThrottlerRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 52: vtctldata.CheckThrottlerResponse.tablet_alias:type_name -> topodata.TabletAlias - 321, // 53: vtctldata.CheckThrottlerResponse.Check:type_name -> tabletmanagerdata.CheckThrottlerResponse - 278, // 54: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - 279, // 55: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - 322, // 56: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType - 309, // 57: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time - 9, // 58: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 9, // 59: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace - 11, // 60: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard - 11, // 61: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard - 310, // 62: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 310, // 63: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 310, // 64: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias - 311, // 65: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 310, // 66: vtctldata.EmergencyReparentShardRequest.expected_primary:type_name -> topodata.TabletAlias - 310, // 67: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 306, // 68: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event - 310, // 69: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias - 323, // 70: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult - 310, // 71: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 323, // 72: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult - 310, // 73: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias - 324, // 74: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest - 325, // 75: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse - 310, // 76: vtctldata.ExecuteMultiFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 323, // 77: vtctldata.ExecuteMultiFetchAsDBAResponse.results:type_name -> query.QueryResult - 280, // 78: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - 281, // 79: vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry - 326, // 80: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo - 313, // 81: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 282, // 82: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry - 310, // 83: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias - 327, // 84: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus - 9, // 85: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace - 9, // 86: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 310, // 87: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias - 328, // 88: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions - 314, // 89: vtctldata.GetKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 315, // 90: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules - 310, // 91: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 329, // 92: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition - 4, // 93: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status - 311, // 94: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration - 1, // 95: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering - 10, // 96: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration - 283, // 97: vtctldata.GetShardReplicationResponse.shard_replication_by_cell:type_name -> vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry - 11, // 98: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard - 316, // 99: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 284, // 100: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - 286, // 101: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - 330, // 102: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule - 331, // 103: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema - 287, // 104: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - 310, // 105: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 320, // 106: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet - 310, // 107: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 319, // 108: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType - 320, // 109: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet - 310, // 110: vtctldata.GetThrottlerStatusRequest.tablet_alias:type_name -> topodata.TabletAlias - 332, // 111: vtctldata.GetThrottlerStatusResponse.status:type_name -> tabletmanagerdata.GetThrottlerStatusResponse - 121, // 112: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell - 333, // 113: vtctldata.GetUnresolvedTransactionsResponse.transactions:type_name -> query.TransactionMetadata - 333, // 114: vtctldata.GetTransactionInfoResponse.metadata:type_name -> query.TransactionMetadata - 125, // 115: vtctldata.GetTransactionInfoResponse.shard_states:type_name -> vtctldata.ShardTransactionState - 334, // 116: vtctldata.ConcludeTransactionRequest.participants:type_name -> query.Target - 310, // 117: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias - 318, // 118: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 13, // 119: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow - 310, // 120: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias - 311, // 121: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration - 306, // 122: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event - 288, // 123: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - 318, // 124: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace - 319, // 125: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType - 307, // 126: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 8, // 127: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings - 319, // 128: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType - 307, // 129: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 319, // 130: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType - 307, // 131: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 12, // 132: vtctldata.MoveTablesCreateRequest.workflow_options:type_name -> vtctldata.WorkflowOptions - 289, // 133: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo - 310, // 134: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 135: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 310, // 136: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias - 311, // 137: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 311, // 138: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration - 310, // 139: vtctldata.PlannedReparentShardRequest.expected_primary:type_name -> topodata.TabletAlias - 310, // 140: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 306, // 141: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 310, // 142: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 143: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 306, // 144: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event - 306, // 145: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event - 310, // 146: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 310, // 147: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 319, // 148: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType - 307, // 149: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 12, // 150: vtctldata.ReshardCreateRequest.workflow_options:type_name -> vtctldata.WorkflowOptions - 310, // 151: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 152: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time - 309, // 153: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time - 310, // 154: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 306, // 155: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event - 290, // 156: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - 310, // 157: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias - 308, // 158: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace - 308, // 159: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace - 312, // 160: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard - 319, // 161: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType - 312, // 162: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard - 310, // 163: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 164: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias - 335, // 165: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError - 291, // 166: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 292, // 167: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 310, // 168: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 169: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 311, // 170: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration - 336, // 171: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange - 312, // 172: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard - 312, // 173: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard - 310, // 174: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 175: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 176: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 310, // 177: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 310, // 178: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 313, // 179: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 313, // 180: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 337, // 181: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 337, // 182: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias - 293, // 183: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry - 294, // 184: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - 295, // 185: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - 296, // 186: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - 297, // 187: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - 319, // 188: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType - 307, // 189: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 311, // 190: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration - 311, // 191: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration - 311, // 192: vtctldata.VDiffCreateRequest.max_diff_duration:type_name -> vttime.Duration - 298, // 193: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry - 299, // 194: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo - 303, // 195: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry - 304, // 196: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry - 319, // 197: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType - 311, // 198: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration - 311, // 199: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration - 338, // 200: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest - 305, // 201: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo - 339, // 202: vtctldata.GetMirrorRulesResponse.mirror_rules:type_name -> vschema.MirrorRules - 319, // 203: vtctldata.WorkflowMirrorTrafficRequest.tablet_types:type_name -> topodata.TabletType - 266, // 204: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream - 267, // 205: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 340, // 206: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 310, // 207: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 341, // 208: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 309, // 209: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 309, // 210: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time - 268, // 211: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 269, // 212: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log - 270, // 213: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus - 319, // 214: vtctldata.Workflow.Stream.tablet_types:type_name -> topodata.TabletType - 307, // 215: vtctldata.Workflow.Stream.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 309, // 216: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time - 309, // 217: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time - 309, // 218: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time - 273, // 219: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry.value:type_name -> vtctldata.ApplyVSchemaResponse.ParamList - 11, // 220: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 337, // 221: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 342, // 222: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry.value:type_name -> topodata.ShardReplication - 285, // 223: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList - 343, // 224: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 331, // 225: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 310, // 226: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 344, // 227: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 320, // 228: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 230, // 229: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse - 234, // 230: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 234, // 231: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 234, // 232: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 234, // 233: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 345, // 234: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse - 310, // 235: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 310, // 236: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias - 301, // 237: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState - 300, // 238: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState - 302, // 239: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams - 310, // 240: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 241, // [241:241] is the sub-list for method output_type - 241, // [241:241] is the sub-list for method input_type - 241, // [241:241] is the sub-list for extension type_name - 241, // [241:241] is the sub-list for extension extendee - 0, // [0:241] is the sub-list for field type_name + 321, // 28: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 322, // 29: vtctldata.ApplyKeyspaceRoutingRulesRequest.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 322, // 30: vtctldata.ApplyKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 323, // 31: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules + 324, // 32: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 319, // 33: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration + 325, // 34: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID + 279, // 35: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + 326, // 36: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace + 326, // 37: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 280, // 38: vtctldata.ApplyVSchemaResponse.unknown_vindex_params:type_name -> vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry + 318, // 39: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 40: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 314, // 41: vtctldata.BackupResponse.event:type_name -> logutil.Event + 282, // 42: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + 318, // 43: vtctldata.ChangeTabletTagsRequest.tablet_alias:type_name -> topodata.TabletAlias + 283, // 44: vtctldata.ChangeTabletTagsRequest.tags:type_name -> vtctldata.ChangeTabletTagsRequest.TagsEntry + 284, // 45: vtctldata.ChangeTabletTagsResponse.before_tags:type_name -> vtctldata.ChangeTabletTagsResponse.BeforeTagsEntry + 285, // 46: vtctldata.ChangeTabletTagsResponse.after_tags:type_name -> vtctldata.ChangeTabletTagsResponse.AfterTagsEntry + 318, // 47: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias + 327, // 48: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType + 328, // 49: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet + 328, // 50: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet + 318, // 51: vtctldata.CheckThrottlerRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 52: vtctldata.CheckThrottlerResponse.tablet_alias:type_name -> topodata.TabletAlias + 329, // 53: vtctldata.CheckThrottlerResponse.Check:type_name -> tabletmanagerdata.CheckThrottlerResponse + 286, // 54: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + 287, // 55: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + 318, // 56: vtctldata.CopySchemaShardRequest.source_tablet_alias:type_name -> topodata.TabletAlias + 319, // 57: vtctldata.CopySchemaShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 330, // 58: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType + 317, // 59: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time + 9, // 60: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace + 9, // 61: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace + 11, // 62: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard + 11, // 63: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard + 318, // 64: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 318, // 65: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 318, // 66: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias + 319, // 67: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 318, // 68: vtctldata.EmergencyReparentShardRequest.expected_primary:type_name -> topodata.TabletAlias + 318, // 69: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 314, // 70: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event + 318, // 71: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias + 331, // 72: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult + 318, // 73: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 331, // 74: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult + 318, // 75: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias + 332, // 76: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest + 333, // 77: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse + 318, // 78: vtctldata.ExecuteMultiFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 331, // 79: vtctldata.ExecuteMultiFetchAsDBAResponse.results:type_name -> query.QueryResult + 288, // 80: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + 289, // 81: vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry + 334, // 82: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo + 321, // 83: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 290, // 84: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry + 318, // 85: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias + 335, // 86: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus + 9, // 87: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace + 9, // 88: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace + 318, // 89: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias + 336, // 90: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions + 322, // 91: vtctldata.GetKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 323, // 92: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules + 318, // 93: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 337, // 94: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition + 4, // 95: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status + 319, // 96: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration + 1, // 97: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering + 10, // 98: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration + 291, // 99: vtctldata.GetShardReplicationResponse.shard_replication_by_cell:type_name -> vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry + 11, // 100: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard + 324, // 101: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 292, // 102: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + 294, // 103: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + 338, // 104: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule + 339, // 105: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema + 295, // 106: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + 318, // 107: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 328, // 108: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet + 318, // 109: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 327, // 110: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType + 328, // 111: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet + 318, // 112: vtctldata.GetThrottlerStatusRequest.tablet_alias:type_name -> topodata.TabletAlias + 340, // 113: vtctldata.GetThrottlerStatusResponse.status:type_name -> tabletmanagerdata.GetThrottlerStatusResponse + 123, // 114: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell + 341, // 115: vtctldata.GetUnresolvedTransactionsResponse.transactions:type_name -> query.TransactionMetadata + 341, // 116: vtctldata.GetTransactionInfoResponse.metadata:type_name -> query.TransactionMetadata + 127, // 117: vtctldata.GetTransactionInfoResponse.shard_states:type_name -> vtctldata.ShardTransactionState + 342, // 118: vtctldata.ConcludeTransactionRequest.participants:type_name -> query.Target + 318, // 119: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias + 326, // 120: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 13, // 121: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow + 318, // 122: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias + 319, // 123: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration + 314, // 124: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event + 296, // 125: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + 326, // 126: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace + 327, // 127: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType + 315, // 128: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 8, // 129: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings + 327, // 130: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType + 315, // 131: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 327, // 132: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType + 315, // 133: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 12, // 134: vtctldata.MoveTablesCreateRequest.workflow_options:type_name -> vtctldata.WorkflowOptions + 297, // 135: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo + 318, // 136: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 137: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 318, // 138: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias + 319, // 139: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 319, // 140: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration + 318, // 141: vtctldata.PlannedReparentShardRequest.expected_primary:type_name -> topodata.TabletAlias + 318, // 142: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 314, // 143: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 318, // 144: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 145: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 314, // 146: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event + 314, // 147: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event + 318, // 148: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 318, // 149: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 327, // 150: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType + 315, // 151: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 12, // 152: vtctldata.ReshardCreateRequest.workflow_options:type_name -> vtctldata.WorkflowOptions + 318, // 153: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 317, // 154: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time + 317, // 155: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time + 318, // 156: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 314, // 157: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event + 298, // 158: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + 318, // 159: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias + 316, // 160: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace + 316, // 161: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace + 320, // 162: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard + 327, // 163: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType + 320, // 164: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard + 318, // 165: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 166: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias + 343, // 167: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError + 299, // 168: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 300, // 169: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 318, // 170: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 171: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 319, // 172: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration + 344, // 173: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange + 320, // 174: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard + 320, // 175: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard + 318, // 176: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 177: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 318, // 178: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 318, // 179: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 318, // 180: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 321, // 181: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 321, // 182: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 345, // 183: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 345, // 184: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 301, // 185: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry + 302, // 186: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + 303, // 187: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + 304, // 188: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + 305, // 189: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + 327, // 190: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType + 315, // 191: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 319, // 192: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration + 319, // 193: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration + 319, // 194: vtctldata.VDiffCreateRequest.max_diff_duration:type_name -> vttime.Duration + 306, // 195: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry + 307, // 196: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo + 311, // 197: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry + 312, // 198: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry + 327, // 199: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType + 319, // 200: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration + 319, // 201: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration + 346, // 202: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest + 313, // 203: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo + 347, // 204: vtctldata.GetMirrorRulesResponse.mirror_rules:type_name -> vschema.MirrorRules + 327, // 205: vtctldata.WorkflowMirrorTrafficRequest.tablet_types:type_name -> topodata.TabletType + 274, // 206: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream + 275, // 207: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream + 348, // 208: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 318, // 209: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 349, // 210: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 317, // 211: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 317, // 212: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 276, // 213: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState + 277, // 214: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 278, // 215: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus + 327, // 216: vtctldata.Workflow.Stream.tablet_types:type_name -> topodata.TabletType + 315, // 217: vtctldata.Workflow.Stream.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 317, // 218: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 317, // 219: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 317, // 220: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time + 281, // 221: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry.value:type_name -> vtctldata.ApplyVSchemaResponse.ParamList + 11, // 222: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 345, // 223: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 350, // 224: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry.value:type_name -> topodata.ShardReplication + 293, // 225: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList + 351, // 226: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 339, // 227: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 318, // 228: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 352, // 229: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 328, // 230: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 236, // 231: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse + 242, // 232: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 242, // 233: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 242, // 234: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 242, // 235: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 353, // 236: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse + 318, // 237: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 318, // 238: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias + 309, // 239: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState + 308, // 240: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState + 310, // 241: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams + 318, // 242: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 243, // [243:243] is the sub-list for method output_type + 243, // [243:243] is the sub-list for method input_type + 243, // [243:243] is the sub-list for extension type_name + 243, // [243:243] is the sub-list for extension extendee + 0, // [0:243] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } @@ -20004,14 +20532,14 @@ func file_vtctldata_proto_init() { return } file_vtctldata_proto_msgTypes[23].OneofWrappers = []any{} - file_vtctldata_proto_msgTypes[236].OneofWrappers = []any{} + file_vtctldata_proto_msgTypes[244].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vtctldata_proto_rawDesc, NumEnums: 5, - NumMessages: 301, + NumMessages: 309, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go index 947b5ce9f43..c9ae1183793 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -1125,6 +1125,54 @@ func (m *CompleteSchemaMigrationResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *CopySchemaShardRequest) CloneVT() *CopySchemaShardRequest { + if m == nil { + return (*CopySchemaShardRequest)(nil) + } + r := new(CopySchemaShardRequest) + r.SourceTabletAlias = m.SourceTabletAlias.CloneVT() + r.IncludeViews = m.IncludeViews + r.SkipVerify = m.SkipVerify + r.WaitReplicasTimeout = m.WaitReplicasTimeout.CloneVT() + r.DestinationKeyspace = m.DestinationKeyspace + r.DestinationShard = m.DestinationShard + if rhs := m.Tables; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.Tables = tmpContainer + } + if rhs := m.ExcludeTables; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.ExcludeTables = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *CopySchemaShardRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *CopySchemaShardResponse) CloneVT() *CopySchemaShardResponse { + if m == nil { + return (*CopySchemaShardResponse)(nil) + } + r := new(CopySchemaShardResponse) + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *CopySchemaShardResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *CreateKeyspaceRequest) CloneVT() *CreateKeyspaceRequest { if m == nil { return (*CreateKeyspaceRequest)(nil) @@ -3052,6 +3100,41 @@ func (m *LaunchSchemaMigrationResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *LookupVindexCompleteRequest) CloneVT() *LookupVindexCompleteRequest { + if m == nil { + return (*LookupVindexCompleteRequest)(nil) + } + r := new(LookupVindexCompleteRequest) + r.Keyspace = m.Keyspace + r.Name = m.Name + r.TableKeyspace = m.TableKeyspace + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *LookupVindexCompleteRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *LookupVindexCompleteResponse) CloneVT() *LookupVindexCompleteResponse { + if m == nil { + return (*LookupVindexCompleteResponse)(nil) + } + r := new(LookupVindexCompleteResponse) + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *LookupVindexCompleteResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *LookupVindexCreateRequest) CloneVT() *LookupVindexCreateRequest { if m == nil { return (*LookupVindexCreateRequest)(nil) @@ -3107,6 +3190,7 @@ func (m *LookupVindexExternalizeRequest) CloneVT() *LookupVindexExternalizeReque r.Keyspace = m.Keyspace r.Name = m.Name r.TableKeyspace = m.TableKeyspace + r.DeleteWorkflow = m.DeleteWorkflow if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -3123,6 +3207,7 @@ func (m *LookupVindexExternalizeResponse) CloneVT() *LookupVindexExternalizeResp return (*LookupVindexExternalizeResponse)(nil) } r := new(LookupVindexExternalizeResponse) + r.WorkflowStopped = m.WorkflowStopped r.WorkflowDeleted = m.WorkflowDeleted if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) @@ -3135,6 +3220,41 @@ func (m *LookupVindexExternalizeResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *LookupVindexInternalizeRequest) CloneVT() *LookupVindexInternalizeRequest { + if m == nil { + return (*LookupVindexInternalizeRequest)(nil) + } + r := new(LookupVindexInternalizeRequest) + r.Keyspace = m.Keyspace + r.Name = m.Name + r.TableKeyspace = m.TableKeyspace + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *LookupVindexInternalizeRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *LookupVindexInternalizeResponse) CloneVT() *LookupVindexInternalizeResponse { + if m == nil { + return (*LookupVindexInternalizeResponse)(nil) + } + r := new(LookupVindexInternalizeResponse) + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *LookupVindexInternalizeResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *MaterializeCreateRequest) CloneVT() *MaterializeCreateRequest { if m == nil { return (*MaterializeCreateRequest)(nil) @@ -4935,6 +5055,44 @@ func (m *ValidateKeyspaceResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *ValidatePermissionsKeyspaceRequest) CloneVT() *ValidatePermissionsKeyspaceRequest { + if m == nil { + return (*ValidatePermissionsKeyspaceRequest)(nil) + } + r := new(ValidatePermissionsKeyspaceRequest) + r.Keyspace = m.Keyspace + if rhs := m.Shards; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.Shards = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *ValidatePermissionsKeyspaceRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *ValidatePermissionsKeyspaceResponse) CloneVT() *ValidatePermissionsKeyspaceResponse { + if m == nil { + return (*ValidatePermissionsKeyspaceResponse)(nil) + } + r := new(ValidatePermissionsKeyspaceResponse) + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *ValidatePermissionsKeyspaceResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *ValidateSchemaKeyspaceRequest) CloneVT() *ValidateSchemaKeyspaceRequest { if m == nil { return (*ValidateSchemaKeyspaceRequest)(nil) @@ -4949,6 +5107,11 @@ func (m *ValidateSchemaKeyspaceRequest) CloneVT() *ValidateSchemaKeyspaceRequest copy(tmpContainer, rhs) r.ExcludeTables = tmpContainer } + if rhs := m.Shards; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.Shards = tmpContainer + } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -9213,6 +9376,144 @@ func (m *CompleteSchemaMigrationResponse) MarshalToSizedBufferVT(dAtA []byte) (i return len(dAtA) - i, nil } +func (m *CopySchemaShardRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CopySchemaShardRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *CopySchemaShardRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.DestinationShard) > 0 { + i -= len(m.DestinationShard) + copy(dAtA[i:], m.DestinationShard) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.DestinationShard))) + i-- + dAtA[i] = 0x42 + } + if len(m.DestinationKeyspace) > 0 { + i -= len(m.DestinationKeyspace) + copy(dAtA[i:], m.DestinationKeyspace) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.DestinationKeyspace))) + i-- + dAtA[i] = 0x3a + } + if m.WaitReplicasTimeout != nil { + size, err := m.WaitReplicasTimeout.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } + if m.SkipVerify { + i-- + if m.SkipVerify { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if m.IncludeViews { + i-- + if m.IncludeViews { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if len(m.ExcludeTables) > 0 { + for iNdEx := len(m.ExcludeTables) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ExcludeTables[iNdEx]) + copy(dAtA[i:], m.ExcludeTables[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ExcludeTables[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Tables) > 0 { + for iNdEx := len(m.Tables) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Tables[iNdEx]) + copy(dAtA[i:], m.Tables[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Tables[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if m.SourceTabletAlias != nil { + size, err := m.SourceTabletAlias.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CopySchemaShardResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CopySchemaShardResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *CopySchemaShardResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + func (m *CreateKeyspaceRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -14117,6 +14418,93 @@ func (m *LaunchSchemaMigrationResponse) MarshalToSizedBufferVT(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *LookupVindexCompleteRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LookupVindexCompleteRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *LookupVindexCompleteRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.TableKeyspace) > 0 { + i -= len(m.TableKeyspace) + copy(dAtA[i:], m.TableKeyspace) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.TableKeyspace))) + i-- + dAtA[i] = 0x1a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.Keyspace) > 0 { + i -= len(m.Keyspace) + copy(dAtA[i:], m.Keyspace) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Keyspace))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LookupVindexCompleteResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LookupVindexCompleteResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *LookupVindexCompleteResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + func (m *LookupVindexCreateRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -14282,6 +14670,16 @@ func (m *LookupVindexExternalizeRequest) MarshalToSizedBufferVT(dAtA []byte) (in i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.DeleteWorkflow { + i-- + if m.DeleteWorkflow { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } if len(m.TableKeyspace) > 0 { i -= len(m.TableKeyspace) copy(dAtA[i:], m.TableKeyspace) @@ -14344,11 +14742,108 @@ func (m *LookupVindexExternalizeResponse) MarshalToSizedBufferVT(dAtA []byte) (i dAtA[i] = 0 } i-- + dAtA[i] = 0x10 + } + if m.WorkflowStopped { + i-- + if m.WorkflowStopped { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- dAtA[i] = 0x8 } return len(dAtA) - i, nil } +func (m *LookupVindexInternalizeRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LookupVindexInternalizeRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *LookupVindexInternalizeRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.TableKeyspace) > 0 { + i -= len(m.TableKeyspace) + copy(dAtA[i:], m.TableKeyspace) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.TableKeyspace))) + i-- + dAtA[i] = 0x1a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.Keyspace) > 0 { + i -= len(m.Keyspace) + copy(dAtA[i:], m.Keyspace) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Keyspace))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LookupVindexInternalizeResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LookupVindexInternalizeResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *LookupVindexInternalizeResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + func (m *MaterializeCreateRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -19246,6 +19741,88 @@ func (m *ValidateKeyspaceResponse) MarshalToSizedBufferVT(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *ValidatePermissionsKeyspaceRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatePermissionsKeyspaceRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ValidatePermissionsKeyspaceRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Shards) > 0 { + for iNdEx := len(m.Shards) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Shards[iNdEx]) + copy(dAtA[i:], m.Shards[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Shards[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Keyspace) > 0 { + i -= len(m.Keyspace) + copy(dAtA[i:], m.Keyspace) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Keyspace))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ValidatePermissionsKeyspaceResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatePermissionsKeyspaceResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ValidatePermissionsKeyspaceResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + func (m *ValidateSchemaKeyspaceRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -19276,6 +19853,15 @@ func (m *ValidateSchemaKeyspaceRequest) MarshalToSizedBufferVT(dAtA []byte) (int i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.Shards) > 0 { + for iNdEx := len(m.Shards) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Shards[iNdEx]) + copy(dAtA[i:], m.Shards[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Shards[iNdEx]))) + i-- + dAtA[i] = 0x32 + } + } if m.IncludeVschema { i-- if m.IncludeVschema { @@ -22908,6 +23494,60 @@ func (m *CompleteSchemaMigrationResponse) SizeVT() (n int) { return n } +func (m *CopySchemaShardRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SourceTabletAlias != nil { + l = m.SourceTabletAlias.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Tables) > 0 { + for _, s := range m.Tables { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.ExcludeTables) > 0 { + for _, s := range m.ExcludeTables { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if m.IncludeViews { + n += 2 + } + if m.SkipVerify { + n += 2 + } + if m.WaitReplicasTimeout != nil { + l = m.WaitReplicasTimeout.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.DestinationKeyspace) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.DestinationShard) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *CopySchemaShardResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + func (m *CreateKeyspaceRequest) SizeVT() (n int) { if m == nil { return 0 @@ -24685,6 +25325,38 @@ func (m *LaunchSchemaMigrationResponse) SizeVT() (n int) { return n } +func (m *LookupVindexCompleteRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Keyspace) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.TableKeyspace) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *LookupVindexCompleteResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + func (m *LookupVindexCreateRequest) SizeVT() (n int) { if m == nil { return 0 @@ -24754,6 +25426,9 @@ func (m *LookupVindexExternalizeRequest) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + if m.DeleteWorkflow { + n += 2 + } n += len(m.unknownFields) return n } @@ -24764,6 +25439,9 @@ func (m *LookupVindexExternalizeResponse) SizeVT() (n int) { } var l int _ = l + if m.WorkflowStopped { + n += 2 + } if m.WorkflowDeleted { n += 2 } @@ -24771,6 +25449,38 @@ func (m *LookupVindexExternalizeResponse) SizeVT() (n int) { return n } +func (m *LookupVindexInternalizeRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Keyspace) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.TableKeyspace) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *LookupVindexInternalizeResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + func (m *MaterializeCreateRequest) SizeVT() (n int) { if m == nil { return 0 @@ -26585,6 +27295,36 @@ func (m *ValidateKeyspaceResponse) SizeVT() (n int) { return n } +func (m *ValidatePermissionsKeyspaceRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Keyspace) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Shards) > 0 { + for _, s := range m.Shards { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *ValidatePermissionsKeyspaceResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + func (m *ValidateSchemaKeyspaceRequest) SizeVT() (n int) { if m == nil { return 0 @@ -26610,6 +27350,12 @@ func (m *ValidateSchemaKeyspaceRequest) SizeVT() (n int) { if m.IncludeVschema { n += 2 } + if len(m.Shards) > 0 { + for _, s := range m.Shards { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } n += len(m.unknownFields) return n } @@ -37033,7 +37779,7 @@ func (m *CompleteSchemaMigrationResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { +func (m *CopySchemaShardRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -37056,17 +37802,17 @@ func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CreateKeyspaceRequest: wiretype end group for non-group") + return fmt.Errorf("proto: CopySchemaShardRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CreateKeyspaceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CopySchemaShardRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SourceTabletAlias", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return protohelpers.ErrIntOverflow @@ -37076,86 +37822,31 @@ func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return protohelpers.ErrInvalidLength } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Force", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + if m.SourceTabletAlias == nil { + m.SourceTabletAlias = &topodata.TabletAlias{} } - m.Force = bool(v != 0) - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowEmptyVSchema", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.AllowEmptyVSchema = bool(v != 0) - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= topodata.KeyspaceType(b&0x7F) << shift - if b < 0x80 { - break - } + if err := m.SourceTabletAlias.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err } - case 8: + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BaseKeyspace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Tables", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -37183,13 +37874,13 @@ func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BaseKeyspace = string(dAtA[iNdEx:postIndex]) + m.Tables = append(m.Tables, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 9: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SnapshotTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ExcludeTables", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protohelpers.ErrIntOverflow @@ -37199,33 +37890,29 @@ func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protohelpers.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return protohelpers.ErrInvalidLength } if postIndex > l { return io.ErrUnexpectedEOF } - if m.SnapshotTime == nil { - m.SnapshotTime = &vttime.Time{} - } - if err := m.SnapshotTime.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ExcludeTables = append(m.ExcludeTables, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DurabilityPolicy", wireType) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IncludeViews", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return protohelpers.ErrIntOverflow @@ -37235,29 +37922,17 @@ func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protohelpers.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protohelpers.ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.DurabilityPolicy = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SidecarDbName", wireType) + m.IncludeViews = bool(v != 0) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SkipVerify", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return protohelpers.ErrIntOverflow @@ -37267,78 +37942,491 @@ func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protohelpers.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protohelpers.ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SidecarDbName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := protohelpers.Skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protohelpers.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CreateKeyspaceResponse) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CreateKeyspaceResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CreateKeyspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + m.SkipVerify = bool(v != 0) + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field WaitReplicasTimeout", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.WaitReplicasTimeout == nil { + m.WaitReplicasTimeout = &vttime.Duration{} + } + if err := m.WaitReplicasTimeout.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DestinationKeyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DestinationKeyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DestinationShard", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DestinationShard = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CopySchemaShardResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CopySchemaShardResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CopySchemaShardResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CreateKeyspaceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreateKeyspaceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Force", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Force = bool(v != 0) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowEmptyVSchema", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AllowEmptyVSchema = bool(v != 0) + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= topodata.KeyspaceType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BaseKeyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BaseKeyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SnapshotTime == nil { + m.SnapshotTime = &vttime.Time{} + } + if err := m.SnapshotTime.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DurabilityPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DurabilityPolicy = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SidecarDbName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SidecarDbName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CreateKeyspaceResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CreateKeyspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreateKeyspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -48202,6 +49290,204 @@ func (m *LaunchSchemaMigrationResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *LookupVindexCompleteRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LookupVindexCompleteRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LookupVindexCompleteRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TableKeyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TableKeyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LookupVindexCompleteResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LookupVindexCompleteResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LookupVindexCompleteResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *LookupVindexCreateRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -48516,12 +49802,270 @@ func (m *LookupVindexCreateResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LookupVindexCreateResponse: wiretype end group for non-group") + return fmt.Errorf("proto: LookupVindexCreateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LookupVindexCreateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LookupVindexExternalizeRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LookupVindexExternalizeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LookupVindexExternalizeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TableKeyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TableKeyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DeleteWorkflow", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DeleteWorkflow = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LookupVindexExternalizeResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LookupVindexExternalizeResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LookupVindexCreateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LookupVindexExternalizeResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WorkflowStopped", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WorkflowStopped = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WorkflowDeleted", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WorkflowDeleted = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -48544,7 +50088,7 @@ func (m *LookupVindexCreateResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *LookupVindexExternalizeRequest) UnmarshalVT(dAtA []byte) error { +func (m *LookupVindexInternalizeRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -48567,10 +50111,10 @@ func (m *LookupVindexExternalizeRequest) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LookupVindexExternalizeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: LookupVindexInternalizeRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LookupVindexExternalizeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LookupVindexInternalizeRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -48691,7 +50235,7 @@ func (m *LookupVindexExternalizeRequest) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *LookupVindexExternalizeResponse) UnmarshalVT(dAtA []byte) error { +func (m *LookupVindexInternalizeResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -48714,32 +50258,12 @@ func (m *LookupVindexExternalizeResponse) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LookupVindexExternalizeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: LookupVindexInternalizeResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LookupVindexExternalizeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LookupVindexInternalizeResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field WorkflowDeleted", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protohelpers.ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.WorkflowDeleted = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -60417,6 +61941,172 @@ func (m *ValidateKeyspaceResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *ValidatePermissionsKeyspaceRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatePermissionsKeyspaceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatePermissionsKeyspaceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Shards", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Shards = append(m.Shards, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatePermissionsKeyspaceResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatePermissionsKeyspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatePermissionsKeyspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ValidateSchemaKeyspaceRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -60570,6 +62260,38 @@ func (m *ValidateSchemaKeyspaceRequest) UnmarshalVT(dAtA []byte) error { } } m.IncludeVschema = bool(v != 0) + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Shards", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Shards = append(m.Shards, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 9ffe2fa9aae..cbd97a8022e 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -51,7 +51,7 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0x85, 0x5b, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, + 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0xc0, 0x5e, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x12, 0x4e, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, @@ -147,643 +147,670 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x43, 0x6f, 0x70, + 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x21, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x70, 0x79, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, + 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x73, 0x12, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, + 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, + 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x51, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, + 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, 0x56, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, - 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x16, 0x45, - 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x45, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6d, 0x65, 0x72, - 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, - 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, - 0x70, 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, - 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, - 0x0a, 0x11, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, - 0x44, 0x42, 0x41, 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, - 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x4c, 0x0a, 0x0b, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x12, - 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x16, 0x45, 0x6d, 0x65, 0x72, 0x67, + 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6d, + 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, + 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, 0x12, 0x23, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x12, + 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, + 0x42, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0b, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x1d, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, + 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, + 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x16, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, + 0x73, 0x44, 0x42, 0x41, 0x12, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x65, 0x74, + 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, - 0x0a, 0x16, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x12, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x65, 0x74, 0x63, 0x68, - 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x72, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, - 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, - 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x7e, 0x0a, 0x1b, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, - 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, - 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x6f, - 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x73, 0x12, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, - 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x4e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, - 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, - 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x5d, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x74, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, + 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x17, 0x46, + 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, + 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, + 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x7e, 0x0a, 0x1b, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, + 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, + 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x1c, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, + 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, + 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x5a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x65, 0x73, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, - 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x47, - 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, - 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x73, 0x12, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, - 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, - 0x09, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x21, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, + 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x46, 0x75, + 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, + 0x0b, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, + 0x0c, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x1e, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x72, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x47, 0x65, 0x74, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x66, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x12, 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, - 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x47, 0x65, 0x74, - 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, - 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x47, - 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1f, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, - 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x47, 0x65, - 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, - 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x63, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, - 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, - 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, - 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, - 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x63, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x55, 0x6e, - 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, - 0x74, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, - 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1c, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x47, - 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x1e, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, - 0x0a, 0x10, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x49, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x47, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, + 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, + 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x72, + 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, + 0x0e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, + 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x1c, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, + 0x12, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, + 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x2b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x6e, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, + 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x49, 0x6e, + 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x22, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, - 0x15, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, - 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x75, 0x6e, - 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x12, 0x4c, - 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, - 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x4c, 0x61, 0x75, + 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, + 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, + 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x72, 0x0a, 0x17, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x29, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x63, 0x0a, 0x12, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x17, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x12, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x17, 0x4c, + 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x6f, + 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x60, 0x0a, 0x11, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, - 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, - 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, - 0x0d, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1f, + 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x55, 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x4d, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, + 0x0a, 0x0f, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x48, 0x0a, 0x09, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x1b, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, - 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x4d, 0x6f, 0x75, - 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x10, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x63, 0x0a, 0x12, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x12, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x69, - 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x69, 0x0a, 0x14, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, - 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, - 0x14, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x52, 0x65, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, - 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x51, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, + 0x0a, 0x10, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, + 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x12, 0x4d, + 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, + 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x4b, 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x1c, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, + 0x14, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, + 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x14, 0x52, 0x65, 0x62, 0x75, + 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, - 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x52, - 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1e, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, - 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x52, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, + 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x14, 0x52, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, + 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x52, 0x65, 0x6c, - 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x23, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x1e, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, - 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, - 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, - 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x57, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x62, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x12, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x12, + 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, + 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, + 0x6c, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x52, 0x65, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x20, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x52, 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x11, 0x52, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, + 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, - 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x30, 0x01, 0x12, 0x69, 0x0a, 0x14, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, - 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6e, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, - 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7e, 0x0a, 0x1b, 0x53, 0x65, 0x74, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, - 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, - 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x53, 0x68, + 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x69, + 0x0a, 0x14, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x52, 0x75, 0x6e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x20, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x7e, 0x0a, 0x1b, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x12, 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x75, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x12, 0x2a, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x6e, 0x67, 0x12, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, - 0x0a, 0x15, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, + 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, - 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x64, 0x64, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x12, 0x25, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, - 0x69, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x19, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x16, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x12, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x6c, 0x65, 0x65, 0x70, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, + 0x6f, 0x6c, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x57, 0x72, + 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x60, 0x0a, 0x11, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x12, 0x25, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x66, 0x0a, 0x13, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x19, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x6f, 0x0a, 0x16, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x28, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6c, + 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6c, 0x65, + 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x41, 0x64, 0x64, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x11, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, - 0x1a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, - 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x2c, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, - 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, - 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x45, 0x0a, 0x08, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x22, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x76, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, + 0x10, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, + 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, 0x70, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x1a, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, + 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, + 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, + 0x08, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x72, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x7e, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x28, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x17, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x26, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, - 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, - 0x70, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, - 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, + 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, + 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x21, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, + 0x73, 0x75, 0x6d, 0x65, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x09, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, + 0x6f, 0x77, 0x12, 0x1b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x48, 0x0a, 0x09, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x1b, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, + 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x6c, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, - 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, - 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, - 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, - 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x69, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, - 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, - 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x6c, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, - 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, - 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, + 0x66, 0x66, 0x69, 0x63, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, + 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x20, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, - 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2b, - 0x5a, 0x29, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x66, 0x66, 0x69, 0x63, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, + 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x76, 0x69, 0x74, + 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, + 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_vtctlservice_proto_goTypes = []any{ @@ -804,233 +831,241 @@ var file_vtctlservice_proto_goTypes = []any{ (*vtctldata.CleanupSchemaMigrationRequest)(nil), // 14: vtctldata.CleanupSchemaMigrationRequest (*vtctldata.CompleteSchemaMigrationRequest)(nil), // 15: vtctldata.CompleteSchemaMigrationRequest (*vtctldata.ConcludeTransactionRequest)(nil), // 16: vtctldata.ConcludeTransactionRequest - (*vtctldata.CreateKeyspaceRequest)(nil), // 17: vtctldata.CreateKeyspaceRequest - (*vtctldata.CreateShardRequest)(nil), // 18: vtctldata.CreateShardRequest - (*vtctldata.DeleteCellInfoRequest)(nil), // 19: vtctldata.DeleteCellInfoRequest - (*vtctldata.DeleteCellsAliasRequest)(nil), // 20: vtctldata.DeleteCellsAliasRequest - (*vtctldata.DeleteKeyspaceRequest)(nil), // 21: vtctldata.DeleteKeyspaceRequest - (*vtctldata.DeleteShardsRequest)(nil), // 22: vtctldata.DeleteShardsRequest - (*vtctldata.DeleteSrvVSchemaRequest)(nil), // 23: vtctldata.DeleteSrvVSchemaRequest - (*vtctldata.DeleteTabletsRequest)(nil), // 24: vtctldata.DeleteTabletsRequest - (*vtctldata.EmergencyReparentShardRequest)(nil), // 25: vtctldata.EmergencyReparentShardRequest - (*vtctldata.ExecuteFetchAsAppRequest)(nil), // 26: vtctldata.ExecuteFetchAsAppRequest - (*vtctldata.ExecuteFetchAsDBARequest)(nil), // 27: vtctldata.ExecuteFetchAsDBARequest - (*vtctldata.ExecuteHookRequest)(nil), // 28: vtctldata.ExecuteHookRequest - (*vtctldata.ExecuteMultiFetchAsDBARequest)(nil), // 29: vtctldata.ExecuteMultiFetchAsDBARequest - (*vtctldata.FindAllShardsInKeyspaceRequest)(nil), // 30: vtctldata.FindAllShardsInKeyspaceRequest - (*vtctldata.ForceCutOverSchemaMigrationRequest)(nil), // 31: vtctldata.ForceCutOverSchemaMigrationRequest - (*vtctldata.GetBackupsRequest)(nil), // 32: vtctldata.GetBackupsRequest - (*vtctldata.GetCellInfoRequest)(nil), // 33: vtctldata.GetCellInfoRequest - (*vtctldata.GetCellInfoNamesRequest)(nil), // 34: vtctldata.GetCellInfoNamesRequest - (*vtctldata.GetCellsAliasesRequest)(nil), // 35: vtctldata.GetCellsAliasesRequest - (*vtctldata.GetFullStatusRequest)(nil), // 36: vtctldata.GetFullStatusRequest - (*vtctldata.GetKeyspaceRequest)(nil), // 37: vtctldata.GetKeyspaceRequest - (*vtctldata.GetKeyspacesRequest)(nil), // 38: vtctldata.GetKeyspacesRequest - (*vtctldata.GetKeyspaceRoutingRulesRequest)(nil), // 39: vtctldata.GetKeyspaceRoutingRulesRequest - (*vtctldata.GetPermissionsRequest)(nil), // 40: vtctldata.GetPermissionsRequest - (*vtctldata.GetRoutingRulesRequest)(nil), // 41: vtctldata.GetRoutingRulesRequest - (*vtctldata.GetSchemaRequest)(nil), // 42: vtctldata.GetSchemaRequest - (*vtctldata.GetSchemaMigrationsRequest)(nil), // 43: vtctldata.GetSchemaMigrationsRequest - (*vtctldata.GetShardReplicationRequest)(nil), // 44: vtctldata.GetShardReplicationRequest - (*vtctldata.GetShardRequest)(nil), // 45: vtctldata.GetShardRequest - (*vtctldata.GetShardRoutingRulesRequest)(nil), // 46: vtctldata.GetShardRoutingRulesRequest - (*vtctldata.GetSrvKeyspaceNamesRequest)(nil), // 47: vtctldata.GetSrvKeyspaceNamesRequest - (*vtctldata.GetSrvKeyspacesRequest)(nil), // 48: vtctldata.GetSrvKeyspacesRequest - (*vtctldata.UpdateThrottlerConfigRequest)(nil), // 49: vtctldata.UpdateThrottlerConfigRequest - (*vtctldata.GetSrvVSchemaRequest)(nil), // 50: vtctldata.GetSrvVSchemaRequest - (*vtctldata.GetSrvVSchemasRequest)(nil), // 51: vtctldata.GetSrvVSchemasRequest - (*vtctldata.GetTabletRequest)(nil), // 52: vtctldata.GetTabletRequest - (*vtctldata.GetTabletsRequest)(nil), // 53: vtctldata.GetTabletsRequest - (*vtctldata.GetThrottlerStatusRequest)(nil), // 54: vtctldata.GetThrottlerStatusRequest - (*vtctldata.GetTopologyPathRequest)(nil), // 55: vtctldata.GetTopologyPathRequest - (*vtctldata.GetTransactionInfoRequest)(nil), // 56: vtctldata.GetTransactionInfoRequest - (*vtctldata.GetUnresolvedTransactionsRequest)(nil), // 57: vtctldata.GetUnresolvedTransactionsRequest - (*vtctldata.GetVersionRequest)(nil), // 58: vtctldata.GetVersionRequest - (*vtctldata.GetVSchemaRequest)(nil), // 59: vtctldata.GetVSchemaRequest - (*vtctldata.GetWorkflowsRequest)(nil), // 60: vtctldata.GetWorkflowsRequest - (*vtctldata.InitShardPrimaryRequest)(nil), // 61: vtctldata.InitShardPrimaryRequest - (*vtctldata.LaunchSchemaMigrationRequest)(nil), // 62: vtctldata.LaunchSchemaMigrationRequest - (*vtctldata.LookupVindexCreateRequest)(nil), // 63: vtctldata.LookupVindexCreateRequest - (*vtctldata.LookupVindexExternalizeRequest)(nil), // 64: vtctldata.LookupVindexExternalizeRequest - (*vtctldata.MaterializeCreateRequest)(nil), // 65: vtctldata.MaterializeCreateRequest - (*vtctldata.MigrateCreateRequest)(nil), // 66: vtctldata.MigrateCreateRequest - (*vtctldata.MountRegisterRequest)(nil), // 67: vtctldata.MountRegisterRequest - (*vtctldata.MountUnregisterRequest)(nil), // 68: vtctldata.MountUnregisterRequest - (*vtctldata.MountShowRequest)(nil), // 69: vtctldata.MountShowRequest - (*vtctldata.MountListRequest)(nil), // 70: vtctldata.MountListRequest - (*vtctldata.MoveTablesCreateRequest)(nil), // 71: vtctldata.MoveTablesCreateRequest - (*vtctldata.MoveTablesCompleteRequest)(nil), // 72: vtctldata.MoveTablesCompleteRequest - (*vtctldata.PingTabletRequest)(nil), // 73: vtctldata.PingTabletRequest - (*vtctldata.PlannedReparentShardRequest)(nil), // 74: vtctldata.PlannedReparentShardRequest - (*vtctldata.RebuildKeyspaceGraphRequest)(nil), // 75: vtctldata.RebuildKeyspaceGraphRequest - (*vtctldata.RebuildVSchemaGraphRequest)(nil), // 76: vtctldata.RebuildVSchemaGraphRequest - (*vtctldata.RefreshStateRequest)(nil), // 77: vtctldata.RefreshStateRequest - (*vtctldata.RefreshStateByShardRequest)(nil), // 78: vtctldata.RefreshStateByShardRequest - (*vtctldata.ReloadSchemaRequest)(nil), // 79: vtctldata.ReloadSchemaRequest - (*vtctldata.ReloadSchemaKeyspaceRequest)(nil), // 80: vtctldata.ReloadSchemaKeyspaceRequest - (*vtctldata.ReloadSchemaShardRequest)(nil), // 81: vtctldata.ReloadSchemaShardRequest - (*vtctldata.RemoveBackupRequest)(nil), // 82: vtctldata.RemoveBackupRequest - (*vtctldata.RemoveKeyspaceCellRequest)(nil), // 83: vtctldata.RemoveKeyspaceCellRequest - (*vtctldata.RemoveShardCellRequest)(nil), // 84: vtctldata.RemoveShardCellRequest - (*vtctldata.ReparentTabletRequest)(nil), // 85: vtctldata.ReparentTabletRequest - (*vtctldata.ReshardCreateRequest)(nil), // 86: vtctldata.ReshardCreateRequest - (*vtctldata.RestoreFromBackupRequest)(nil), // 87: vtctldata.RestoreFromBackupRequest - (*vtctldata.RetrySchemaMigrationRequest)(nil), // 88: vtctldata.RetrySchemaMigrationRequest - (*vtctldata.RunHealthCheckRequest)(nil), // 89: vtctldata.RunHealthCheckRequest - (*vtctldata.SetKeyspaceDurabilityPolicyRequest)(nil), // 90: vtctldata.SetKeyspaceDurabilityPolicyRequest - (*vtctldata.SetShardIsPrimaryServingRequest)(nil), // 91: vtctldata.SetShardIsPrimaryServingRequest - (*vtctldata.SetShardTabletControlRequest)(nil), // 92: vtctldata.SetShardTabletControlRequest - (*vtctldata.SetWritableRequest)(nil), // 93: vtctldata.SetWritableRequest - (*vtctldata.ShardReplicationAddRequest)(nil), // 94: vtctldata.ShardReplicationAddRequest - (*vtctldata.ShardReplicationFixRequest)(nil), // 95: vtctldata.ShardReplicationFixRequest - (*vtctldata.ShardReplicationPositionsRequest)(nil), // 96: vtctldata.ShardReplicationPositionsRequest - (*vtctldata.ShardReplicationRemoveRequest)(nil), // 97: vtctldata.ShardReplicationRemoveRequest - (*vtctldata.SleepTabletRequest)(nil), // 98: vtctldata.SleepTabletRequest - (*vtctldata.SourceShardAddRequest)(nil), // 99: vtctldata.SourceShardAddRequest - (*vtctldata.SourceShardDeleteRequest)(nil), // 100: vtctldata.SourceShardDeleteRequest - (*vtctldata.StartReplicationRequest)(nil), // 101: vtctldata.StartReplicationRequest - (*vtctldata.StopReplicationRequest)(nil), // 102: vtctldata.StopReplicationRequest - (*vtctldata.TabletExternallyReparentedRequest)(nil), // 103: vtctldata.TabletExternallyReparentedRequest - (*vtctldata.UpdateCellInfoRequest)(nil), // 104: vtctldata.UpdateCellInfoRequest - (*vtctldata.UpdateCellsAliasRequest)(nil), // 105: vtctldata.UpdateCellsAliasRequest - (*vtctldata.ValidateRequest)(nil), // 106: vtctldata.ValidateRequest - (*vtctldata.ValidateKeyspaceRequest)(nil), // 107: vtctldata.ValidateKeyspaceRequest - (*vtctldata.ValidateSchemaKeyspaceRequest)(nil), // 108: vtctldata.ValidateSchemaKeyspaceRequest - (*vtctldata.ValidateShardRequest)(nil), // 109: vtctldata.ValidateShardRequest - (*vtctldata.ValidateVersionKeyspaceRequest)(nil), // 110: vtctldata.ValidateVersionKeyspaceRequest - (*vtctldata.ValidateVersionShardRequest)(nil), // 111: vtctldata.ValidateVersionShardRequest - (*vtctldata.ValidateVSchemaRequest)(nil), // 112: vtctldata.ValidateVSchemaRequest - (*vtctldata.VDiffCreateRequest)(nil), // 113: vtctldata.VDiffCreateRequest - (*vtctldata.VDiffDeleteRequest)(nil), // 114: vtctldata.VDiffDeleteRequest - (*vtctldata.VDiffResumeRequest)(nil), // 115: vtctldata.VDiffResumeRequest - (*vtctldata.VDiffShowRequest)(nil), // 116: vtctldata.VDiffShowRequest - (*vtctldata.VDiffStopRequest)(nil), // 117: vtctldata.VDiffStopRequest - (*vtctldata.WorkflowDeleteRequest)(nil), // 118: vtctldata.WorkflowDeleteRequest - (*vtctldata.WorkflowStatusRequest)(nil), // 119: vtctldata.WorkflowStatusRequest - (*vtctldata.WorkflowSwitchTrafficRequest)(nil), // 120: vtctldata.WorkflowSwitchTrafficRequest - (*vtctldata.WorkflowUpdateRequest)(nil), // 121: vtctldata.WorkflowUpdateRequest - (*vtctldata.GetMirrorRulesRequest)(nil), // 122: vtctldata.GetMirrorRulesRequest - (*vtctldata.WorkflowMirrorTrafficRequest)(nil), // 123: vtctldata.WorkflowMirrorTrafficRequest - (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 124: vtctldata.ExecuteVtctlCommandResponse - (*vtctldata.AddCellInfoResponse)(nil), // 125: vtctldata.AddCellInfoResponse - (*vtctldata.AddCellsAliasResponse)(nil), // 126: vtctldata.AddCellsAliasResponse - (*vtctldata.ApplyRoutingRulesResponse)(nil), // 127: vtctldata.ApplyRoutingRulesResponse - (*vtctldata.ApplySchemaResponse)(nil), // 128: vtctldata.ApplySchemaResponse - (*vtctldata.ApplyKeyspaceRoutingRulesResponse)(nil), // 129: vtctldata.ApplyKeyspaceRoutingRulesResponse - (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 130: vtctldata.ApplyShardRoutingRulesResponse - (*vtctldata.ApplyVSchemaResponse)(nil), // 131: vtctldata.ApplyVSchemaResponse - (*vtctldata.BackupResponse)(nil), // 132: vtctldata.BackupResponse - (*vtctldata.CancelSchemaMigrationResponse)(nil), // 133: vtctldata.CancelSchemaMigrationResponse - (*vtctldata.ChangeTabletTagsResponse)(nil), // 134: vtctldata.ChangeTabletTagsResponse - (*vtctldata.ChangeTabletTypeResponse)(nil), // 135: vtctldata.ChangeTabletTypeResponse - (*vtctldata.CheckThrottlerResponse)(nil), // 136: vtctldata.CheckThrottlerResponse - (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 137: vtctldata.CleanupSchemaMigrationResponse - (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 138: vtctldata.CompleteSchemaMigrationResponse - (*vtctldata.ConcludeTransactionResponse)(nil), // 139: vtctldata.ConcludeTransactionResponse - (*vtctldata.CreateKeyspaceResponse)(nil), // 140: vtctldata.CreateKeyspaceResponse - (*vtctldata.CreateShardResponse)(nil), // 141: vtctldata.CreateShardResponse - (*vtctldata.DeleteCellInfoResponse)(nil), // 142: vtctldata.DeleteCellInfoResponse - (*vtctldata.DeleteCellsAliasResponse)(nil), // 143: vtctldata.DeleteCellsAliasResponse - (*vtctldata.DeleteKeyspaceResponse)(nil), // 144: vtctldata.DeleteKeyspaceResponse - (*vtctldata.DeleteShardsResponse)(nil), // 145: vtctldata.DeleteShardsResponse - (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 146: vtctldata.DeleteSrvVSchemaResponse - (*vtctldata.DeleteTabletsResponse)(nil), // 147: vtctldata.DeleteTabletsResponse - (*vtctldata.EmergencyReparentShardResponse)(nil), // 148: vtctldata.EmergencyReparentShardResponse - (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 149: vtctldata.ExecuteFetchAsAppResponse - (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 150: vtctldata.ExecuteFetchAsDBAResponse - (*vtctldata.ExecuteHookResponse)(nil), // 151: vtctldata.ExecuteHookResponse - (*vtctldata.ExecuteMultiFetchAsDBAResponse)(nil), // 152: vtctldata.ExecuteMultiFetchAsDBAResponse - (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 153: vtctldata.FindAllShardsInKeyspaceResponse - (*vtctldata.ForceCutOverSchemaMigrationResponse)(nil), // 154: vtctldata.ForceCutOverSchemaMigrationResponse - (*vtctldata.GetBackupsResponse)(nil), // 155: vtctldata.GetBackupsResponse - (*vtctldata.GetCellInfoResponse)(nil), // 156: vtctldata.GetCellInfoResponse - (*vtctldata.GetCellInfoNamesResponse)(nil), // 157: vtctldata.GetCellInfoNamesResponse - (*vtctldata.GetCellsAliasesResponse)(nil), // 158: vtctldata.GetCellsAliasesResponse - (*vtctldata.GetFullStatusResponse)(nil), // 159: vtctldata.GetFullStatusResponse - (*vtctldata.GetKeyspaceResponse)(nil), // 160: vtctldata.GetKeyspaceResponse - (*vtctldata.GetKeyspacesResponse)(nil), // 161: vtctldata.GetKeyspacesResponse - (*vtctldata.GetKeyspaceRoutingRulesResponse)(nil), // 162: vtctldata.GetKeyspaceRoutingRulesResponse - (*vtctldata.GetPermissionsResponse)(nil), // 163: vtctldata.GetPermissionsResponse - (*vtctldata.GetRoutingRulesResponse)(nil), // 164: vtctldata.GetRoutingRulesResponse - (*vtctldata.GetSchemaResponse)(nil), // 165: vtctldata.GetSchemaResponse - (*vtctldata.GetSchemaMigrationsResponse)(nil), // 166: vtctldata.GetSchemaMigrationsResponse - (*vtctldata.GetShardReplicationResponse)(nil), // 167: vtctldata.GetShardReplicationResponse - (*vtctldata.GetShardResponse)(nil), // 168: vtctldata.GetShardResponse - (*vtctldata.GetShardRoutingRulesResponse)(nil), // 169: vtctldata.GetShardRoutingRulesResponse - (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 170: vtctldata.GetSrvKeyspaceNamesResponse - (*vtctldata.GetSrvKeyspacesResponse)(nil), // 171: vtctldata.GetSrvKeyspacesResponse - (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 172: vtctldata.UpdateThrottlerConfigResponse - (*vtctldata.GetSrvVSchemaResponse)(nil), // 173: vtctldata.GetSrvVSchemaResponse - (*vtctldata.GetSrvVSchemasResponse)(nil), // 174: vtctldata.GetSrvVSchemasResponse - (*vtctldata.GetTabletResponse)(nil), // 175: vtctldata.GetTabletResponse - (*vtctldata.GetTabletsResponse)(nil), // 176: vtctldata.GetTabletsResponse - (*vtctldata.GetThrottlerStatusResponse)(nil), // 177: vtctldata.GetThrottlerStatusResponse - (*vtctldata.GetTopologyPathResponse)(nil), // 178: vtctldata.GetTopologyPathResponse - (*vtctldata.GetTransactionInfoResponse)(nil), // 179: vtctldata.GetTransactionInfoResponse - (*vtctldata.GetUnresolvedTransactionsResponse)(nil), // 180: vtctldata.GetUnresolvedTransactionsResponse - (*vtctldata.GetVersionResponse)(nil), // 181: vtctldata.GetVersionResponse - (*vtctldata.GetVSchemaResponse)(nil), // 182: vtctldata.GetVSchemaResponse - (*vtctldata.GetWorkflowsResponse)(nil), // 183: vtctldata.GetWorkflowsResponse - (*vtctldata.InitShardPrimaryResponse)(nil), // 184: vtctldata.InitShardPrimaryResponse - (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 185: vtctldata.LaunchSchemaMigrationResponse - (*vtctldata.LookupVindexCreateResponse)(nil), // 186: vtctldata.LookupVindexCreateResponse - (*vtctldata.LookupVindexExternalizeResponse)(nil), // 187: vtctldata.LookupVindexExternalizeResponse - (*vtctldata.MaterializeCreateResponse)(nil), // 188: vtctldata.MaterializeCreateResponse - (*vtctldata.WorkflowStatusResponse)(nil), // 189: vtctldata.WorkflowStatusResponse - (*vtctldata.MountRegisterResponse)(nil), // 190: vtctldata.MountRegisterResponse - (*vtctldata.MountUnregisterResponse)(nil), // 191: vtctldata.MountUnregisterResponse - (*vtctldata.MountShowResponse)(nil), // 192: vtctldata.MountShowResponse - (*vtctldata.MountListResponse)(nil), // 193: vtctldata.MountListResponse - (*vtctldata.MoveTablesCompleteResponse)(nil), // 194: vtctldata.MoveTablesCompleteResponse - (*vtctldata.PingTabletResponse)(nil), // 195: vtctldata.PingTabletResponse - (*vtctldata.PlannedReparentShardResponse)(nil), // 196: vtctldata.PlannedReparentShardResponse - (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 197: vtctldata.RebuildKeyspaceGraphResponse - (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 198: vtctldata.RebuildVSchemaGraphResponse - (*vtctldata.RefreshStateResponse)(nil), // 199: vtctldata.RefreshStateResponse - (*vtctldata.RefreshStateByShardResponse)(nil), // 200: vtctldata.RefreshStateByShardResponse - (*vtctldata.ReloadSchemaResponse)(nil), // 201: vtctldata.ReloadSchemaResponse - (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 202: vtctldata.ReloadSchemaKeyspaceResponse - (*vtctldata.ReloadSchemaShardResponse)(nil), // 203: vtctldata.ReloadSchemaShardResponse - (*vtctldata.RemoveBackupResponse)(nil), // 204: vtctldata.RemoveBackupResponse - (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 205: vtctldata.RemoveKeyspaceCellResponse - (*vtctldata.RemoveShardCellResponse)(nil), // 206: vtctldata.RemoveShardCellResponse - (*vtctldata.ReparentTabletResponse)(nil), // 207: vtctldata.ReparentTabletResponse - (*vtctldata.RestoreFromBackupResponse)(nil), // 208: vtctldata.RestoreFromBackupResponse - (*vtctldata.RetrySchemaMigrationResponse)(nil), // 209: vtctldata.RetrySchemaMigrationResponse - (*vtctldata.RunHealthCheckResponse)(nil), // 210: vtctldata.RunHealthCheckResponse - (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 211: vtctldata.SetKeyspaceDurabilityPolicyResponse - (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 212: vtctldata.SetShardIsPrimaryServingResponse - (*vtctldata.SetShardTabletControlResponse)(nil), // 213: vtctldata.SetShardTabletControlResponse - (*vtctldata.SetWritableResponse)(nil), // 214: vtctldata.SetWritableResponse - (*vtctldata.ShardReplicationAddResponse)(nil), // 215: vtctldata.ShardReplicationAddResponse - (*vtctldata.ShardReplicationFixResponse)(nil), // 216: vtctldata.ShardReplicationFixResponse - (*vtctldata.ShardReplicationPositionsResponse)(nil), // 217: vtctldata.ShardReplicationPositionsResponse - (*vtctldata.ShardReplicationRemoveResponse)(nil), // 218: vtctldata.ShardReplicationRemoveResponse - (*vtctldata.SleepTabletResponse)(nil), // 219: vtctldata.SleepTabletResponse - (*vtctldata.SourceShardAddResponse)(nil), // 220: vtctldata.SourceShardAddResponse - (*vtctldata.SourceShardDeleteResponse)(nil), // 221: vtctldata.SourceShardDeleteResponse - (*vtctldata.StartReplicationResponse)(nil), // 222: vtctldata.StartReplicationResponse - (*vtctldata.StopReplicationResponse)(nil), // 223: vtctldata.StopReplicationResponse - (*vtctldata.TabletExternallyReparentedResponse)(nil), // 224: vtctldata.TabletExternallyReparentedResponse - (*vtctldata.UpdateCellInfoResponse)(nil), // 225: vtctldata.UpdateCellInfoResponse - (*vtctldata.UpdateCellsAliasResponse)(nil), // 226: vtctldata.UpdateCellsAliasResponse - (*vtctldata.ValidateResponse)(nil), // 227: vtctldata.ValidateResponse - (*vtctldata.ValidateKeyspaceResponse)(nil), // 228: vtctldata.ValidateKeyspaceResponse - (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 229: vtctldata.ValidateSchemaKeyspaceResponse - (*vtctldata.ValidateShardResponse)(nil), // 230: vtctldata.ValidateShardResponse - (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 231: vtctldata.ValidateVersionKeyspaceResponse - (*vtctldata.ValidateVersionShardResponse)(nil), // 232: vtctldata.ValidateVersionShardResponse - (*vtctldata.ValidateVSchemaResponse)(nil), // 233: vtctldata.ValidateVSchemaResponse - (*vtctldata.VDiffCreateResponse)(nil), // 234: vtctldata.VDiffCreateResponse - (*vtctldata.VDiffDeleteResponse)(nil), // 235: vtctldata.VDiffDeleteResponse - (*vtctldata.VDiffResumeResponse)(nil), // 236: vtctldata.VDiffResumeResponse - (*vtctldata.VDiffShowResponse)(nil), // 237: vtctldata.VDiffShowResponse - (*vtctldata.VDiffStopResponse)(nil), // 238: vtctldata.VDiffStopResponse - (*vtctldata.WorkflowDeleteResponse)(nil), // 239: vtctldata.WorkflowDeleteResponse - (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 240: vtctldata.WorkflowSwitchTrafficResponse - (*vtctldata.WorkflowUpdateResponse)(nil), // 241: vtctldata.WorkflowUpdateResponse - (*vtctldata.GetMirrorRulesResponse)(nil), // 242: vtctldata.GetMirrorRulesResponse - (*vtctldata.WorkflowMirrorTrafficResponse)(nil), // 243: vtctldata.WorkflowMirrorTrafficResponse + (*vtctldata.CopySchemaShardRequest)(nil), // 17: vtctldata.CopySchemaShardRequest + (*vtctldata.CreateKeyspaceRequest)(nil), // 18: vtctldata.CreateKeyspaceRequest + (*vtctldata.CreateShardRequest)(nil), // 19: vtctldata.CreateShardRequest + (*vtctldata.DeleteCellInfoRequest)(nil), // 20: vtctldata.DeleteCellInfoRequest + (*vtctldata.DeleteCellsAliasRequest)(nil), // 21: vtctldata.DeleteCellsAliasRequest + (*vtctldata.DeleteKeyspaceRequest)(nil), // 22: vtctldata.DeleteKeyspaceRequest + (*vtctldata.DeleteShardsRequest)(nil), // 23: vtctldata.DeleteShardsRequest + (*vtctldata.DeleteSrvVSchemaRequest)(nil), // 24: vtctldata.DeleteSrvVSchemaRequest + (*vtctldata.DeleteTabletsRequest)(nil), // 25: vtctldata.DeleteTabletsRequest + (*vtctldata.EmergencyReparentShardRequest)(nil), // 26: vtctldata.EmergencyReparentShardRequest + (*vtctldata.ExecuteFetchAsAppRequest)(nil), // 27: vtctldata.ExecuteFetchAsAppRequest + (*vtctldata.ExecuteFetchAsDBARequest)(nil), // 28: vtctldata.ExecuteFetchAsDBARequest + (*vtctldata.ExecuteHookRequest)(nil), // 29: vtctldata.ExecuteHookRequest + (*vtctldata.ExecuteMultiFetchAsDBARequest)(nil), // 30: vtctldata.ExecuteMultiFetchAsDBARequest + (*vtctldata.FindAllShardsInKeyspaceRequest)(nil), // 31: vtctldata.FindAllShardsInKeyspaceRequest + (*vtctldata.ForceCutOverSchemaMigrationRequest)(nil), // 32: vtctldata.ForceCutOverSchemaMigrationRequest + (*vtctldata.GetBackupsRequest)(nil), // 33: vtctldata.GetBackupsRequest + (*vtctldata.GetCellInfoRequest)(nil), // 34: vtctldata.GetCellInfoRequest + (*vtctldata.GetCellInfoNamesRequest)(nil), // 35: vtctldata.GetCellInfoNamesRequest + (*vtctldata.GetCellsAliasesRequest)(nil), // 36: vtctldata.GetCellsAliasesRequest + (*vtctldata.GetFullStatusRequest)(nil), // 37: vtctldata.GetFullStatusRequest + (*vtctldata.GetKeyspaceRequest)(nil), // 38: vtctldata.GetKeyspaceRequest + (*vtctldata.GetKeyspacesRequest)(nil), // 39: vtctldata.GetKeyspacesRequest + (*vtctldata.GetKeyspaceRoutingRulesRequest)(nil), // 40: vtctldata.GetKeyspaceRoutingRulesRequest + (*vtctldata.GetPermissionsRequest)(nil), // 41: vtctldata.GetPermissionsRequest + (*vtctldata.GetRoutingRulesRequest)(nil), // 42: vtctldata.GetRoutingRulesRequest + (*vtctldata.GetSchemaRequest)(nil), // 43: vtctldata.GetSchemaRequest + (*vtctldata.GetSchemaMigrationsRequest)(nil), // 44: vtctldata.GetSchemaMigrationsRequest + (*vtctldata.GetShardReplicationRequest)(nil), // 45: vtctldata.GetShardReplicationRequest + (*vtctldata.GetShardRequest)(nil), // 46: vtctldata.GetShardRequest + (*vtctldata.GetShardRoutingRulesRequest)(nil), // 47: vtctldata.GetShardRoutingRulesRequest + (*vtctldata.GetSrvKeyspaceNamesRequest)(nil), // 48: vtctldata.GetSrvKeyspaceNamesRequest + (*vtctldata.GetSrvKeyspacesRequest)(nil), // 49: vtctldata.GetSrvKeyspacesRequest + (*vtctldata.UpdateThrottlerConfigRequest)(nil), // 50: vtctldata.UpdateThrottlerConfigRequest + (*vtctldata.GetSrvVSchemaRequest)(nil), // 51: vtctldata.GetSrvVSchemaRequest + (*vtctldata.GetSrvVSchemasRequest)(nil), // 52: vtctldata.GetSrvVSchemasRequest + (*vtctldata.GetTabletRequest)(nil), // 53: vtctldata.GetTabletRequest + (*vtctldata.GetTabletsRequest)(nil), // 54: vtctldata.GetTabletsRequest + (*vtctldata.GetThrottlerStatusRequest)(nil), // 55: vtctldata.GetThrottlerStatusRequest + (*vtctldata.GetTopologyPathRequest)(nil), // 56: vtctldata.GetTopologyPathRequest + (*vtctldata.GetTransactionInfoRequest)(nil), // 57: vtctldata.GetTransactionInfoRequest + (*vtctldata.GetUnresolvedTransactionsRequest)(nil), // 58: vtctldata.GetUnresolvedTransactionsRequest + (*vtctldata.GetVersionRequest)(nil), // 59: vtctldata.GetVersionRequest + (*vtctldata.GetVSchemaRequest)(nil), // 60: vtctldata.GetVSchemaRequest + (*vtctldata.GetWorkflowsRequest)(nil), // 61: vtctldata.GetWorkflowsRequest + (*vtctldata.InitShardPrimaryRequest)(nil), // 62: vtctldata.InitShardPrimaryRequest + (*vtctldata.LaunchSchemaMigrationRequest)(nil), // 63: vtctldata.LaunchSchemaMigrationRequest + (*vtctldata.LookupVindexCompleteRequest)(nil), // 64: vtctldata.LookupVindexCompleteRequest + (*vtctldata.LookupVindexCreateRequest)(nil), // 65: vtctldata.LookupVindexCreateRequest + (*vtctldata.LookupVindexExternalizeRequest)(nil), // 66: vtctldata.LookupVindexExternalizeRequest + (*vtctldata.LookupVindexInternalizeRequest)(nil), // 67: vtctldata.LookupVindexInternalizeRequest + (*vtctldata.MaterializeCreateRequest)(nil), // 68: vtctldata.MaterializeCreateRequest + (*vtctldata.MigrateCreateRequest)(nil), // 69: vtctldata.MigrateCreateRequest + (*vtctldata.MountRegisterRequest)(nil), // 70: vtctldata.MountRegisterRequest + (*vtctldata.MountUnregisterRequest)(nil), // 71: vtctldata.MountUnregisterRequest + (*vtctldata.MountShowRequest)(nil), // 72: vtctldata.MountShowRequest + (*vtctldata.MountListRequest)(nil), // 73: vtctldata.MountListRequest + (*vtctldata.MoveTablesCreateRequest)(nil), // 74: vtctldata.MoveTablesCreateRequest + (*vtctldata.MoveTablesCompleteRequest)(nil), // 75: vtctldata.MoveTablesCompleteRequest + (*vtctldata.PingTabletRequest)(nil), // 76: vtctldata.PingTabletRequest + (*vtctldata.PlannedReparentShardRequest)(nil), // 77: vtctldata.PlannedReparentShardRequest + (*vtctldata.RebuildKeyspaceGraphRequest)(nil), // 78: vtctldata.RebuildKeyspaceGraphRequest + (*vtctldata.RebuildVSchemaGraphRequest)(nil), // 79: vtctldata.RebuildVSchemaGraphRequest + (*vtctldata.RefreshStateRequest)(nil), // 80: vtctldata.RefreshStateRequest + (*vtctldata.RefreshStateByShardRequest)(nil), // 81: vtctldata.RefreshStateByShardRequest + (*vtctldata.ReloadSchemaRequest)(nil), // 82: vtctldata.ReloadSchemaRequest + (*vtctldata.ReloadSchemaKeyspaceRequest)(nil), // 83: vtctldata.ReloadSchemaKeyspaceRequest + (*vtctldata.ReloadSchemaShardRequest)(nil), // 84: vtctldata.ReloadSchemaShardRequest + (*vtctldata.RemoveBackupRequest)(nil), // 85: vtctldata.RemoveBackupRequest + (*vtctldata.RemoveKeyspaceCellRequest)(nil), // 86: vtctldata.RemoveKeyspaceCellRequest + (*vtctldata.RemoveShardCellRequest)(nil), // 87: vtctldata.RemoveShardCellRequest + (*vtctldata.ReparentTabletRequest)(nil), // 88: vtctldata.ReparentTabletRequest + (*vtctldata.ReshardCreateRequest)(nil), // 89: vtctldata.ReshardCreateRequest + (*vtctldata.RestoreFromBackupRequest)(nil), // 90: vtctldata.RestoreFromBackupRequest + (*vtctldata.RetrySchemaMigrationRequest)(nil), // 91: vtctldata.RetrySchemaMigrationRequest + (*vtctldata.RunHealthCheckRequest)(nil), // 92: vtctldata.RunHealthCheckRequest + (*vtctldata.SetKeyspaceDurabilityPolicyRequest)(nil), // 93: vtctldata.SetKeyspaceDurabilityPolicyRequest + (*vtctldata.SetShardIsPrimaryServingRequest)(nil), // 94: vtctldata.SetShardIsPrimaryServingRequest + (*vtctldata.SetShardTabletControlRequest)(nil), // 95: vtctldata.SetShardTabletControlRequest + (*vtctldata.SetWritableRequest)(nil), // 96: vtctldata.SetWritableRequest + (*vtctldata.ShardReplicationAddRequest)(nil), // 97: vtctldata.ShardReplicationAddRequest + (*vtctldata.ShardReplicationFixRequest)(nil), // 98: vtctldata.ShardReplicationFixRequest + (*vtctldata.ShardReplicationPositionsRequest)(nil), // 99: vtctldata.ShardReplicationPositionsRequest + (*vtctldata.ShardReplicationRemoveRequest)(nil), // 100: vtctldata.ShardReplicationRemoveRequest + (*vtctldata.SleepTabletRequest)(nil), // 101: vtctldata.SleepTabletRequest + (*vtctldata.SourceShardAddRequest)(nil), // 102: vtctldata.SourceShardAddRequest + (*vtctldata.SourceShardDeleteRequest)(nil), // 103: vtctldata.SourceShardDeleteRequest + (*vtctldata.StartReplicationRequest)(nil), // 104: vtctldata.StartReplicationRequest + (*vtctldata.StopReplicationRequest)(nil), // 105: vtctldata.StopReplicationRequest + (*vtctldata.TabletExternallyReparentedRequest)(nil), // 106: vtctldata.TabletExternallyReparentedRequest + (*vtctldata.UpdateCellInfoRequest)(nil), // 107: vtctldata.UpdateCellInfoRequest + (*vtctldata.UpdateCellsAliasRequest)(nil), // 108: vtctldata.UpdateCellsAliasRequest + (*vtctldata.ValidateRequest)(nil), // 109: vtctldata.ValidateRequest + (*vtctldata.ValidateKeyspaceRequest)(nil), // 110: vtctldata.ValidateKeyspaceRequest + (*vtctldata.ValidatePermissionsKeyspaceRequest)(nil), // 111: vtctldata.ValidatePermissionsKeyspaceRequest + (*vtctldata.ValidateSchemaKeyspaceRequest)(nil), // 112: vtctldata.ValidateSchemaKeyspaceRequest + (*vtctldata.ValidateShardRequest)(nil), // 113: vtctldata.ValidateShardRequest + (*vtctldata.ValidateVersionKeyspaceRequest)(nil), // 114: vtctldata.ValidateVersionKeyspaceRequest + (*vtctldata.ValidateVersionShardRequest)(nil), // 115: vtctldata.ValidateVersionShardRequest + (*vtctldata.ValidateVSchemaRequest)(nil), // 116: vtctldata.ValidateVSchemaRequest + (*vtctldata.VDiffCreateRequest)(nil), // 117: vtctldata.VDiffCreateRequest + (*vtctldata.VDiffDeleteRequest)(nil), // 118: vtctldata.VDiffDeleteRequest + (*vtctldata.VDiffResumeRequest)(nil), // 119: vtctldata.VDiffResumeRequest + (*vtctldata.VDiffShowRequest)(nil), // 120: vtctldata.VDiffShowRequest + (*vtctldata.VDiffStopRequest)(nil), // 121: vtctldata.VDiffStopRequest + (*vtctldata.WorkflowDeleteRequest)(nil), // 122: vtctldata.WorkflowDeleteRequest + (*vtctldata.WorkflowStatusRequest)(nil), // 123: vtctldata.WorkflowStatusRequest + (*vtctldata.WorkflowSwitchTrafficRequest)(nil), // 124: vtctldata.WorkflowSwitchTrafficRequest + (*vtctldata.WorkflowUpdateRequest)(nil), // 125: vtctldata.WorkflowUpdateRequest + (*vtctldata.GetMirrorRulesRequest)(nil), // 126: vtctldata.GetMirrorRulesRequest + (*vtctldata.WorkflowMirrorTrafficRequest)(nil), // 127: vtctldata.WorkflowMirrorTrafficRequest + (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 128: vtctldata.ExecuteVtctlCommandResponse + (*vtctldata.AddCellInfoResponse)(nil), // 129: vtctldata.AddCellInfoResponse + (*vtctldata.AddCellsAliasResponse)(nil), // 130: vtctldata.AddCellsAliasResponse + (*vtctldata.ApplyRoutingRulesResponse)(nil), // 131: vtctldata.ApplyRoutingRulesResponse + (*vtctldata.ApplySchemaResponse)(nil), // 132: vtctldata.ApplySchemaResponse + (*vtctldata.ApplyKeyspaceRoutingRulesResponse)(nil), // 133: vtctldata.ApplyKeyspaceRoutingRulesResponse + (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 134: vtctldata.ApplyShardRoutingRulesResponse + (*vtctldata.ApplyVSchemaResponse)(nil), // 135: vtctldata.ApplyVSchemaResponse + (*vtctldata.BackupResponse)(nil), // 136: vtctldata.BackupResponse + (*vtctldata.CancelSchemaMigrationResponse)(nil), // 137: vtctldata.CancelSchemaMigrationResponse + (*vtctldata.ChangeTabletTagsResponse)(nil), // 138: vtctldata.ChangeTabletTagsResponse + (*vtctldata.ChangeTabletTypeResponse)(nil), // 139: vtctldata.ChangeTabletTypeResponse + (*vtctldata.CheckThrottlerResponse)(nil), // 140: vtctldata.CheckThrottlerResponse + (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 141: vtctldata.CleanupSchemaMigrationResponse + (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 142: vtctldata.CompleteSchemaMigrationResponse + (*vtctldata.ConcludeTransactionResponse)(nil), // 143: vtctldata.ConcludeTransactionResponse + (*vtctldata.CopySchemaShardResponse)(nil), // 144: vtctldata.CopySchemaShardResponse + (*vtctldata.CreateKeyspaceResponse)(nil), // 145: vtctldata.CreateKeyspaceResponse + (*vtctldata.CreateShardResponse)(nil), // 146: vtctldata.CreateShardResponse + (*vtctldata.DeleteCellInfoResponse)(nil), // 147: vtctldata.DeleteCellInfoResponse + (*vtctldata.DeleteCellsAliasResponse)(nil), // 148: vtctldata.DeleteCellsAliasResponse + (*vtctldata.DeleteKeyspaceResponse)(nil), // 149: vtctldata.DeleteKeyspaceResponse + (*vtctldata.DeleteShardsResponse)(nil), // 150: vtctldata.DeleteShardsResponse + (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 151: vtctldata.DeleteSrvVSchemaResponse + (*vtctldata.DeleteTabletsResponse)(nil), // 152: vtctldata.DeleteTabletsResponse + (*vtctldata.EmergencyReparentShardResponse)(nil), // 153: vtctldata.EmergencyReparentShardResponse + (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 154: vtctldata.ExecuteFetchAsAppResponse + (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 155: vtctldata.ExecuteFetchAsDBAResponse + (*vtctldata.ExecuteHookResponse)(nil), // 156: vtctldata.ExecuteHookResponse + (*vtctldata.ExecuteMultiFetchAsDBAResponse)(nil), // 157: vtctldata.ExecuteMultiFetchAsDBAResponse + (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 158: vtctldata.FindAllShardsInKeyspaceResponse + (*vtctldata.ForceCutOverSchemaMigrationResponse)(nil), // 159: vtctldata.ForceCutOverSchemaMigrationResponse + (*vtctldata.GetBackupsResponse)(nil), // 160: vtctldata.GetBackupsResponse + (*vtctldata.GetCellInfoResponse)(nil), // 161: vtctldata.GetCellInfoResponse + (*vtctldata.GetCellInfoNamesResponse)(nil), // 162: vtctldata.GetCellInfoNamesResponse + (*vtctldata.GetCellsAliasesResponse)(nil), // 163: vtctldata.GetCellsAliasesResponse + (*vtctldata.GetFullStatusResponse)(nil), // 164: vtctldata.GetFullStatusResponse + (*vtctldata.GetKeyspaceResponse)(nil), // 165: vtctldata.GetKeyspaceResponse + (*vtctldata.GetKeyspacesResponse)(nil), // 166: vtctldata.GetKeyspacesResponse + (*vtctldata.GetKeyspaceRoutingRulesResponse)(nil), // 167: vtctldata.GetKeyspaceRoutingRulesResponse + (*vtctldata.GetPermissionsResponse)(nil), // 168: vtctldata.GetPermissionsResponse + (*vtctldata.GetRoutingRulesResponse)(nil), // 169: vtctldata.GetRoutingRulesResponse + (*vtctldata.GetSchemaResponse)(nil), // 170: vtctldata.GetSchemaResponse + (*vtctldata.GetSchemaMigrationsResponse)(nil), // 171: vtctldata.GetSchemaMigrationsResponse + (*vtctldata.GetShardReplicationResponse)(nil), // 172: vtctldata.GetShardReplicationResponse + (*vtctldata.GetShardResponse)(nil), // 173: vtctldata.GetShardResponse + (*vtctldata.GetShardRoutingRulesResponse)(nil), // 174: vtctldata.GetShardRoutingRulesResponse + (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 175: vtctldata.GetSrvKeyspaceNamesResponse + (*vtctldata.GetSrvKeyspacesResponse)(nil), // 176: vtctldata.GetSrvKeyspacesResponse + (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 177: vtctldata.UpdateThrottlerConfigResponse + (*vtctldata.GetSrvVSchemaResponse)(nil), // 178: vtctldata.GetSrvVSchemaResponse + (*vtctldata.GetSrvVSchemasResponse)(nil), // 179: vtctldata.GetSrvVSchemasResponse + (*vtctldata.GetTabletResponse)(nil), // 180: vtctldata.GetTabletResponse + (*vtctldata.GetTabletsResponse)(nil), // 181: vtctldata.GetTabletsResponse + (*vtctldata.GetThrottlerStatusResponse)(nil), // 182: vtctldata.GetThrottlerStatusResponse + (*vtctldata.GetTopologyPathResponse)(nil), // 183: vtctldata.GetTopologyPathResponse + (*vtctldata.GetTransactionInfoResponse)(nil), // 184: vtctldata.GetTransactionInfoResponse + (*vtctldata.GetUnresolvedTransactionsResponse)(nil), // 185: vtctldata.GetUnresolvedTransactionsResponse + (*vtctldata.GetVersionResponse)(nil), // 186: vtctldata.GetVersionResponse + (*vtctldata.GetVSchemaResponse)(nil), // 187: vtctldata.GetVSchemaResponse + (*vtctldata.GetWorkflowsResponse)(nil), // 188: vtctldata.GetWorkflowsResponse + (*vtctldata.InitShardPrimaryResponse)(nil), // 189: vtctldata.InitShardPrimaryResponse + (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 190: vtctldata.LaunchSchemaMigrationResponse + (*vtctldata.LookupVindexCompleteResponse)(nil), // 191: vtctldata.LookupVindexCompleteResponse + (*vtctldata.LookupVindexCreateResponse)(nil), // 192: vtctldata.LookupVindexCreateResponse + (*vtctldata.LookupVindexExternalizeResponse)(nil), // 193: vtctldata.LookupVindexExternalizeResponse + (*vtctldata.LookupVindexInternalizeResponse)(nil), // 194: vtctldata.LookupVindexInternalizeResponse + (*vtctldata.MaterializeCreateResponse)(nil), // 195: vtctldata.MaterializeCreateResponse + (*vtctldata.WorkflowStatusResponse)(nil), // 196: vtctldata.WorkflowStatusResponse + (*vtctldata.MountRegisterResponse)(nil), // 197: vtctldata.MountRegisterResponse + (*vtctldata.MountUnregisterResponse)(nil), // 198: vtctldata.MountUnregisterResponse + (*vtctldata.MountShowResponse)(nil), // 199: vtctldata.MountShowResponse + (*vtctldata.MountListResponse)(nil), // 200: vtctldata.MountListResponse + (*vtctldata.MoveTablesCompleteResponse)(nil), // 201: vtctldata.MoveTablesCompleteResponse + (*vtctldata.PingTabletResponse)(nil), // 202: vtctldata.PingTabletResponse + (*vtctldata.PlannedReparentShardResponse)(nil), // 203: vtctldata.PlannedReparentShardResponse + (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 204: vtctldata.RebuildKeyspaceGraphResponse + (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 205: vtctldata.RebuildVSchemaGraphResponse + (*vtctldata.RefreshStateResponse)(nil), // 206: vtctldata.RefreshStateResponse + (*vtctldata.RefreshStateByShardResponse)(nil), // 207: vtctldata.RefreshStateByShardResponse + (*vtctldata.ReloadSchemaResponse)(nil), // 208: vtctldata.ReloadSchemaResponse + (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 209: vtctldata.ReloadSchemaKeyspaceResponse + (*vtctldata.ReloadSchemaShardResponse)(nil), // 210: vtctldata.ReloadSchemaShardResponse + (*vtctldata.RemoveBackupResponse)(nil), // 211: vtctldata.RemoveBackupResponse + (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 212: vtctldata.RemoveKeyspaceCellResponse + (*vtctldata.RemoveShardCellResponse)(nil), // 213: vtctldata.RemoveShardCellResponse + (*vtctldata.ReparentTabletResponse)(nil), // 214: vtctldata.ReparentTabletResponse + (*vtctldata.RestoreFromBackupResponse)(nil), // 215: vtctldata.RestoreFromBackupResponse + (*vtctldata.RetrySchemaMigrationResponse)(nil), // 216: vtctldata.RetrySchemaMigrationResponse + (*vtctldata.RunHealthCheckResponse)(nil), // 217: vtctldata.RunHealthCheckResponse + (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 218: vtctldata.SetKeyspaceDurabilityPolicyResponse + (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 219: vtctldata.SetShardIsPrimaryServingResponse + (*vtctldata.SetShardTabletControlResponse)(nil), // 220: vtctldata.SetShardTabletControlResponse + (*vtctldata.SetWritableResponse)(nil), // 221: vtctldata.SetWritableResponse + (*vtctldata.ShardReplicationAddResponse)(nil), // 222: vtctldata.ShardReplicationAddResponse + (*vtctldata.ShardReplicationFixResponse)(nil), // 223: vtctldata.ShardReplicationFixResponse + (*vtctldata.ShardReplicationPositionsResponse)(nil), // 224: vtctldata.ShardReplicationPositionsResponse + (*vtctldata.ShardReplicationRemoveResponse)(nil), // 225: vtctldata.ShardReplicationRemoveResponse + (*vtctldata.SleepTabletResponse)(nil), // 226: vtctldata.SleepTabletResponse + (*vtctldata.SourceShardAddResponse)(nil), // 227: vtctldata.SourceShardAddResponse + (*vtctldata.SourceShardDeleteResponse)(nil), // 228: vtctldata.SourceShardDeleteResponse + (*vtctldata.StartReplicationResponse)(nil), // 229: vtctldata.StartReplicationResponse + (*vtctldata.StopReplicationResponse)(nil), // 230: vtctldata.StopReplicationResponse + (*vtctldata.TabletExternallyReparentedResponse)(nil), // 231: vtctldata.TabletExternallyReparentedResponse + (*vtctldata.UpdateCellInfoResponse)(nil), // 232: vtctldata.UpdateCellInfoResponse + (*vtctldata.UpdateCellsAliasResponse)(nil), // 233: vtctldata.UpdateCellsAliasResponse + (*vtctldata.ValidateResponse)(nil), // 234: vtctldata.ValidateResponse + (*vtctldata.ValidateKeyspaceResponse)(nil), // 235: vtctldata.ValidateKeyspaceResponse + (*vtctldata.ValidatePermissionsKeyspaceResponse)(nil), // 236: vtctldata.ValidatePermissionsKeyspaceResponse + (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 237: vtctldata.ValidateSchemaKeyspaceResponse + (*vtctldata.ValidateShardResponse)(nil), // 238: vtctldata.ValidateShardResponse + (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 239: vtctldata.ValidateVersionKeyspaceResponse + (*vtctldata.ValidateVersionShardResponse)(nil), // 240: vtctldata.ValidateVersionShardResponse + (*vtctldata.ValidateVSchemaResponse)(nil), // 241: vtctldata.ValidateVSchemaResponse + (*vtctldata.VDiffCreateResponse)(nil), // 242: vtctldata.VDiffCreateResponse + (*vtctldata.VDiffDeleteResponse)(nil), // 243: vtctldata.VDiffDeleteResponse + (*vtctldata.VDiffResumeResponse)(nil), // 244: vtctldata.VDiffResumeResponse + (*vtctldata.VDiffShowResponse)(nil), // 245: vtctldata.VDiffShowResponse + (*vtctldata.VDiffStopResponse)(nil), // 246: vtctldata.VDiffStopResponse + (*vtctldata.WorkflowDeleteResponse)(nil), // 247: vtctldata.WorkflowDeleteResponse + (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 248: vtctldata.WorkflowSwitchTrafficResponse + (*vtctldata.WorkflowUpdateResponse)(nil), // 249: vtctldata.WorkflowUpdateResponse + (*vtctldata.GetMirrorRulesResponse)(nil), // 250: vtctldata.GetMirrorRulesResponse + (*vtctldata.WorkflowMirrorTrafficResponse)(nil), // 251: vtctldata.WorkflowMirrorTrafficResponse } var file_vtctlservice_proto_depIdxs = []int32{ 0, // 0: vtctlservice.Vtctl.ExecuteVtctlCommand:input_type -> vtctldata.ExecuteVtctlCommandRequest @@ -1050,239 +1085,247 @@ var file_vtctlservice_proto_depIdxs = []int32{ 14, // 14: vtctlservice.Vtctld.CleanupSchemaMigration:input_type -> vtctldata.CleanupSchemaMigrationRequest 15, // 15: vtctlservice.Vtctld.CompleteSchemaMigration:input_type -> vtctldata.CompleteSchemaMigrationRequest 16, // 16: vtctlservice.Vtctld.ConcludeTransaction:input_type -> vtctldata.ConcludeTransactionRequest - 17, // 17: vtctlservice.Vtctld.CreateKeyspace:input_type -> vtctldata.CreateKeyspaceRequest - 18, // 18: vtctlservice.Vtctld.CreateShard:input_type -> vtctldata.CreateShardRequest - 19, // 19: vtctlservice.Vtctld.DeleteCellInfo:input_type -> vtctldata.DeleteCellInfoRequest - 20, // 20: vtctlservice.Vtctld.DeleteCellsAlias:input_type -> vtctldata.DeleteCellsAliasRequest - 21, // 21: vtctlservice.Vtctld.DeleteKeyspace:input_type -> vtctldata.DeleteKeyspaceRequest - 22, // 22: vtctlservice.Vtctld.DeleteShards:input_type -> vtctldata.DeleteShardsRequest - 23, // 23: vtctlservice.Vtctld.DeleteSrvVSchema:input_type -> vtctldata.DeleteSrvVSchemaRequest - 24, // 24: vtctlservice.Vtctld.DeleteTablets:input_type -> vtctldata.DeleteTabletsRequest - 25, // 25: vtctlservice.Vtctld.EmergencyReparentShard:input_type -> vtctldata.EmergencyReparentShardRequest - 26, // 26: vtctlservice.Vtctld.ExecuteFetchAsApp:input_type -> vtctldata.ExecuteFetchAsAppRequest - 27, // 27: vtctlservice.Vtctld.ExecuteFetchAsDBA:input_type -> vtctldata.ExecuteFetchAsDBARequest - 28, // 28: vtctlservice.Vtctld.ExecuteHook:input_type -> vtctldata.ExecuteHookRequest - 29, // 29: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:input_type -> vtctldata.ExecuteMultiFetchAsDBARequest - 30, // 30: vtctlservice.Vtctld.FindAllShardsInKeyspace:input_type -> vtctldata.FindAllShardsInKeyspaceRequest - 31, // 31: vtctlservice.Vtctld.ForceCutOverSchemaMigration:input_type -> vtctldata.ForceCutOverSchemaMigrationRequest - 32, // 32: vtctlservice.Vtctld.GetBackups:input_type -> vtctldata.GetBackupsRequest - 33, // 33: vtctlservice.Vtctld.GetCellInfo:input_type -> vtctldata.GetCellInfoRequest - 34, // 34: vtctlservice.Vtctld.GetCellInfoNames:input_type -> vtctldata.GetCellInfoNamesRequest - 35, // 35: vtctlservice.Vtctld.GetCellsAliases:input_type -> vtctldata.GetCellsAliasesRequest - 36, // 36: vtctlservice.Vtctld.GetFullStatus:input_type -> vtctldata.GetFullStatusRequest - 37, // 37: vtctlservice.Vtctld.GetKeyspace:input_type -> vtctldata.GetKeyspaceRequest - 38, // 38: vtctlservice.Vtctld.GetKeyspaces:input_type -> vtctldata.GetKeyspacesRequest - 39, // 39: vtctlservice.Vtctld.GetKeyspaceRoutingRules:input_type -> vtctldata.GetKeyspaceRoutingRulesRequest - 40, // 40: vtctlservice.Vtctld.GetPermissions:input_type -> vtctldata.GetPermissionsRequest - 41, // 41: vtctlservice.Vtctld.GetRoutingRules:input_type -> vtctldata.GetRoutingRulesRequest - 42, // 42: vtctlservice.Vtctld.GetSchema:input_type -> vtctldata.GetSchemaRequest - 43, // 43: vtctlservice.Vtctld.GetSchemaMigrations:input_type -> vtctldata.GetSchemaMigrationsRequest - 44, // 44: vtctlservice.Vtctld.GetShardReplication:input_type -> vtctldata.GetShardReplicationRequest - 45, // 45: vtctlservice.Vtctld.GetShard:input_type -> vtctldata.GetShardRequest - 46, // 46: vtctlservice.Vtctld.GetShardRoutingRules:input_type -> vtctldata.GetShardRoutingRulesRequest - 47, // 47: vtctlservice.Vtctld.GetSrvKeyspaceNames:input_type -> vtctldata.GetSrvKeyspaceNamesRequest - 48, // 48: vtctlservice.Vtctld.GetSrvKeyspaces:input_type -> vtctldata.GetSrvKeyspacesRequest - 49, // 49: vtctlservice.Vtctld.UpdateThrottlerConfig:input_type -> vtctldata.UpdateThrottlerConfigRequest - 50, // 50: vtctlservice.Vtctld.GetSrvVSchema:input_type -> vtctldata.GetSrvVSchemaRequest - 51, // 51: vtctlservice.Vtctld.GetSrvVSchemas:input_type -> vtctldata.GetSrvVSchemasRequest - 52, // 52: vtctlservice.Vtctld.GetTablet:input_type -> vtctldata.GetTabletRequest - 53, // 53: vtctlservice.Vtctld.GetTablets:input_type -> vtctldata.GetTabletsRequest - 54, // 54: vtctlservice.Vtctld.GetThrottlerStatus:input_type -> vtctldata.GetThrottlerStatusRequest - 55, // 55: vtctlservice.Vtctld.GetTopologyPath:input_type -> vtctldata.GetTopologyPathRequest - 56, // 56: vtctlservice.Vtctld.GetTransactionInfo:input_type -> vtctldata.GetTransactionInfoRequest - 57, // 57: vtctlservice.Vtctld.GetUnresolvedTransactions:input_type -> vtctldata.GetUnresolvedTransactionsRequest - 58, // 58: vtctlservice.Vtctld.GetVersion:input_type -> vtctldata.GetVersionRequest - 59, // 59: vtctlservice.Vtctld.GetVSchema:input_type -> vtctldata.GetVSchemaRequest - 60, // 60: vtctlservice.Vtctld.GetWorkflows:input_type -> vtctldata.GetWorkflowsRequest - 61, // 61: vtctlservice.Vtctld.InitShardPrimary:input_type -> vtctldata.InitShardPrimaryRequest - 62, // 62: vtctlservice.Vtctld.LaunchSchemaMigration:input_type -> vtctldata.LaunchSchemaMigrationRequest - 63, // 63: vtctlservice.Vtctld.LookupVindexCreate:input_type -> vtctldata.LookupVindexCreateRequest - 64, // 64: vtctlservice.Vtctld.LookupVindexExternalize:input_type -> vtctldata.LookupVindexExternalizeRequest - 65, // 65: vtctlservice.Vtctld.MaterializeCreate:input_type -> vtctldata.MaterializeCreateRequest - 66, // 66: vtctlservice.Vtctld.MigrateCreate:input_type -> vtctldata.MigrateCreateRequest - 67, // 67: vtctlservice.Vtctld.MountRegister:input_type -> vtctldata.MountRegisterRequest - 68, // 68: vtctlservice.Vtctld.MountUnregister:input_type -> vtctldata.MountUnregisterRequest - 69, // 69: vtctlservice.Vtctld.MountShow:input_type -> vtctldata.MountShowRequest - 70, // 70: vtctlservice.Vtctld.MountList:input_type -> vtctldata.MountListRequest - 71, // 71: vtctlservice.Vtctld.MoveTablesCreate:input_type -> vtctldata.MoveTablesCreateRequest - 72, // 72: vtctlservice.Vtctld.MoveTablesComplete:input_type -> vtctldata.MoveTablesCompleteRequest - 73, // 73: vtctlservice.Vtctld.PingTablet:input_type -> vtctldata.PingTabletRequest - 74, // 74: vtctlservice.Vtctld.PlannedReparentShard:input_type -> vtctldata.PlannedReparentShardRequest - 75, // 75: vtctlservice.Vtctld.RebuildKeyspaceGraph:input_type -> vtctldata.RebuildKeyspaceGraphRequest - 76, // 76: vtctlservice.Vtctld.RebuildVSchemaGraph:input_type -> vtctldata.RebuildVSchemaGraphRequest - 77, // 77: vtctlservice.Vtctld.RefreshState:input_type -> vtctldata.RefreshStateRequest - 78, // 78: vtctlservice.Vtctld.RefreshStateByShard:input_type -> vtctldata.RefreshStateByShardRequest - 79, // 79: vtctlservice.Vtctld.ReloadSchema:input_type -> vtctldata.ReloadSchemaRequest - 80, // 80: vtctlservice.Vtctld.ReloadSchemaKeyspace:input_type -> vtctldata.ReloadSchemaKeyspaceRequest - 81, // 81: vtctlservice.Vtctld.ReloadSchemaShard:input_type -> vtctldata.ReloadSchemaShardRequest - 82, // 82: vtctlservice.Vtctld.RemoveBackup:input_type -> vtctldata.RemoveBackupRequest - 83, // 83: vtctlservice.Vtctld.RemoveKeyspaceCell:input_type -> vtctldata.RemoveKeyspaceCellRequest - 84, // 84: vtctlservice.Vtctld.RemoveShardCell:input_type -> vtctldata.RemoveShardCellRequest - 85, // 85: vtctlservice.Vtctld.ReparentTablet:input_type -> vtctldata.ReparentTabletRequest - 86, // 86: vtctlservice.Vtctld.ReshardCreate:input_type -> vtctldata.ReshardCreateRequest - 87, // 87: vtctlservice.Vtctld.RestoreFromBackup:input_type -> vtctldata.RestoreFromBackupRequest - 88, // 88: vtctlservice.Vtctld.RetrySchemaMigration:input_type -> vtctldata.RetrySchemaMigrationRequest - 89, // 89: vtctlservice.Vtctld.RunHealthCheck:input_type -> vtctldata.RunHealthCheckRequest - 90, // 90: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:input_type -> vtctldata.SetKeyspaceDurabilityPolicyRequest - 91, // 91: vtctlservice.Vtctld.SetShardIsPrimaryServing:input_type -> vtctldata.SetShardIsPrimaryServingRequest - 92, // 92: vtctlservice.Vtctld.SetShardTabletControl:input_type -> vtctldata.SetShardTabletControlRequest - 93, // 93: vtctlservice.Vtctld.SetWritable:input_type -> vtctldata.SetWritableRequest - 94, // 94: vtctlservice.Vtctld.ShardReplicationAdd:input_type -> vtctldata.ShardReplicationAddRequest - 95, // 95: vtctlservice.Vtctld.ShardReplicationFix:input_type -> vtctldata.ShardReplicationFixRequest - 96, // 96: vtctlservice.Vtctld.ShardReplicationPositions:input_type -> vtctldata.ShardReplicationPositionsRequest - 97, // 97: vtctlservice.Vtctld.ShardReplicationRemove:input_type -> vtctldata.ShardReplicationRemoveRequest - 98, // 98: vtctlservice.Vtctld.SleepTablet:input_type -> vtctldata.SleepTabletRequest - 99, // 99: vtctlservice.Vtctld.SourceShardAdd:input_type -> vtctldata.SourceShardAddRequest - 100, // 100: vtctlservice.Vtctld.SourceShardDelete:input_type -> vtctldata.SourceShardDeleteRequest - 101, // 101: vtctlservice.Vtctld.StartReplication:input_type -> vtctldata.StartReplicationRequest - 102, // 102: vtctlservice.Vtctld.StopReplication:input_type -> vtctldata.StopReplicationRequest - 103, // 103: vtctlservice.Vtctld.TabletExternallyReparented:input_type -> vtctldata.TabletExternallyReparentedRequest - 104, // 104: vtctlservice.Vtctld.UpdateCellInfo:input_type -> vtctldata.UpdateCellInfoRequest - 105, // 105: vtctlservice.Vtctld.UpdateCellsAlias:input_type -> vtctldata.UpdateCellsAliasRequest - 106, // 106: vtctlservice.Vtctld.Validate:input_type -> vtctldata.ValidateRequest - 107, // 107: vtctlservice.Vtctld.ValidateKeyspace:input_type -> vtctldata.ValidateKeyspaceRequest - 108, // 108: vtctlservice.Vtctld.ValidateSchemaKeyspace:input_type -> vtctldata.ValidateSchemaKeyspaceRequest - 109, // 109: vtctlservice.Vtctld.ValidateShard:input_type -> vtctldata.ValidateShardRequest - 110, // 110: vtctlservice.Vtctld.ValidateVersionKeyspace:input_type -> vtctldata.ValidateVersionKeyspaceRequest - 111, // 111: vtctlservice.Vtctld.ValidateVersionShard:input_type -> vtctldata.ValidateVersionShardRequest - 112, // 112: vtctlservice.Vtctld.ValidateVSchema:input_type -> vtctldata.ValidateVSchemaRequest - 113, // 113: vtctlservice.Vtctld.VDiffCreate:input_type -> vtctldata.VDiffCreateRequest - 114, // 114: vtctlservice.Vtctld.VDiffDelete:input_type -> vtctldata.VDiffDeleteRequest - 115, // 115: vtctlservice.Vtctld.VDiffResume:input_type -> vtctldata.VDiffResumeRequest - 116, // 116: vtctlservice.Vtctld.VDiffShow:input_type -> vtctldata.VDiffShowRequest - 117, // 117: vtctlservice.Vtctld.VDiffStop:input_type -> vtctldata.VDiffStopRequest - 118, // 118: vtctlservice.Vtctld.WorkflowDelete:input_type -> vtctldata.WorkflowDeleteRequest - 119, // 119: vtctlservice.Vtctld.WorkflowStatus:input_type -> vtctldata.WorkflowStatusRequest - 120, // 120: vtctlservice.Vtctld.WorkflowSwitchTraffic:input_type -> vtctldata.WorkflowSwitchTrafficRequest - 121, // 121: vtctlservice.Vtctld.WorkflowUpdate:input_type -> vtctldata.WorkflowUpdateRequest - 122, // 122: vtctlservice.Vtctld.GetMirrorRules:input_type -> vtctldata.GetMirrorRulesRequest - 123, // 123: vtctlservice.Vtctld.WorkflowMirrorTraffic:input_type -> vtctldata.WorkflowMirrorTrafficRequest - 124, // 124: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse - 125, // 125: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse - 126, // 126: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse - 127, // 127: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse - 128, // 128: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse - 129, // 129: vtctlservice.Vtctld.ApplyKeyspaceRoutingRules:output_type -> vtctldata.ApplyKeyspaceRoutingRulesResponse - 130, // 130: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse - 131, // 131: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse - 132, // 132: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse - 132, // 133: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse - 133, // 134: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse - 134, // 135: vtctlservice.Vtctld.ChangeTabletTags:output_type -> vtctldata.ChangeTabletTagsResponse - 135, // 136: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse - 136, // 137: vtctlservice.Vtctld.CheckThrottler:output_type -> vtctldata.CheckThrottlerResponse - 137, // 138: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse - 138, // 139: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse - 139, // 140: vtctlservice.Vtctld.ConcludeTransaction:output_type -> vtctldata.ConcludeTransactionResponse - 140, // 141: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse - 141, // 142: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse - 142, // 143: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse - 143, // 144: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse - 144, // 145: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse - 145, // 146: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse - 146, // 147: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse - 147, // 148: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse - 148, // 149: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse - 149, // 150: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse - 150, // 151: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse - 151, // 152: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse - 152, // 153: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:output_type -> vtctldata.ExecuteMultiFetchAsDBAResponse - 153, // 154: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse - 154, // 155: vtctlservice.Vtctld.ForceCutOverSchemaMigration:output_type -> vtctldata.ForceCutOverSchemaMigrationResponse - 155, // 156: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse - 156, // 157: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse - 157, // 158: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse - 158, // 159: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse - 159, // 160: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse - 160, // 161: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse - 161, // 162: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse - 162, // 163: vtctlservice.Vtctld.GetKeyspaceRoutingRules:output_type -> vtctldata.GetKeyspaceRoutingRulesResponse - 163, // 164: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse - 164, // 165: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse - 165, // 166: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse - 166, // 167: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse - 167, // 168: vtctlservice.Vtctld.GetShardReplication:output_type -> vtctldata.GetShardReplicationResponse - 168, // 169: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse - 169, // 170: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse - 170, // 171: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse - 171, // 172: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse - 172, // 173: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse - 173, // 174: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse - 174, // 175: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse - 175, // 176: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse - 176, // 177: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse - 177, // 178: vtctlservice.Vtctld.GetThrottlerStatus:output_type -> vtctldata.GetThrottlerStatusResponse - 178, // 179: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse - 179, // 180: vtctlservice.Vtctld.GetTransactionInfo:output_type -> vtctldata.GetTransactionInfoResponse - 180, // 181: vtctlservice.Vtctld.GetUnresolvedTransactions:output_type -> vtctldata.GetUnresolvedTransactionsResponse - 181, // 182: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse - 182, // 183: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse - 183, // 184: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse - 184, // 185: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse - 185, // 186: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse - 186, // 187: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse - 187, // 188: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse - 188, // 189: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse - 189, // 190: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse - 190, // 191: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse - 191, // 192: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse - 192, // 193: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse - 193, // 194: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse - 189, // 195: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse - 194, // 196: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse - 195, // 197: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse - 196, // 198: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse - 197, // 199: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse - 198, // 200: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse - 199, // 201: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse - 200, // 202: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse - 201, // 203: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse - 202, // 204: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse - 203, // 205: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse - 204, // 206: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse - 205, // 207: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse - 206, // 208: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse - 207, // 209: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse - 189, // 210: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse - 208, // 211: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse - 209, // 212: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse - 210, // 213: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse - 211, // 214: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse - 212, // 215: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse - 213, // 216: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse - 214, // 217: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse - 215, // 218: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse - 216, // 219: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse - 217, // 220: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse - 218, // 221: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse - 219, // 222: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse - 220, // 223: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse - 221, // 224: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse - 222, // 225: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse - 223, // 226: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse - 224, // 227: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse - 225, // 228: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse - 226, // 229: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse - 227, // 230: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse - 228, // 231: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse - 229, // 232: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse - 230, // 233: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse - 231, // 234: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse - 232, // 235: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse - 233, // 236: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse - 234, // 237: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse - 235, // 238: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse - 236, // 239: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse - 237, // 240: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse - 238, // 241: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse - 239, // 242: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse - 189, // 243: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse - 240, // 244: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse - 241, // 245: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse - 242, // 246: vtctlservice.Vtctld.GetMirrorRules:output_type -> vtctldata.GetMirrorRulesResponse - 243, // 247: vtctlservice.Vtctld.WorkflowMirrorTraffic:output_type -> vtctldata.WorkflowMirrorTrafficResponse - 124, // [124:248] is the sub-list for method output_type - 0, // [0:124] is the sub-list for method input_type + 17, // 17: vtctlservice.Vtctld.CopySchemaShard:input_type -> vtctldata.CopySchemaShardRequest + 18, // 18: vtctlservice.Vtctld.CreateKeyspace:input_type -> vtctldata.CreateKeyspaceRequest + 19, // 19: vtctlservice.Vtctld.CreateShard:input_type -> vtctldata.CreateShardRequest + 20, // 20: vtctlservice.Vtctld.DeleteCellInfo:input_type -> vtctldata.DeleteCellInfoRequest + 21, // 21: vtctlservice.Vtctld.DeleteCellsAlias:input_type -> vtctldata.DeleteCellsAliasRequest + 22, // 22: vtctlservice.Vtctld.DeleteKeyspace:input_type -> vtctldata.DeleteKeyspaceRequest + 23, // 23: vtctlservice.Vtctld.DeleteShards:input_type -> vtctldata.DeleteShardsRequest + 24, // 24: vtctlservice.Vtctld.DeleteSrvVSchema:input_type -> vtctldata.DeleteSrvVSchemaRequest + 25, // 25: vtctlservice.Vtctld.DeleteTablets:input_type -> vtctldata.DeleteTabletsRequest + 26, // 26: vtctlservice.Vtctld.EmergencyReparentShard:input_type -> vtctldata.EmergencyReparentShardRequest + 27, // 27: vtctlservice.Vtctld.ExecuteFetchAsApp:input_type -> vtctldata.ExecuteFetchAsAppRequest + 28, // 28: vtctlservice.Vtctld.ExecuteFetchAsDBA:input_type -> vtctldata.ExecuteFetchAsDBARequest + 29, // 29: vtctlservice.Vtctld.ExecuteHook:input_type -> vtctldata.ExecuteHookRequest + 30, // 30: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:input_type -> vtctldata.ExecuteMultiFetchAsDBARequest + 31, // 31: vtctlservice.Vtctld.FindAllShardsInKeyspace:input_type -> vtctldata.FindAllShardsInKeyspaceRequest + 32, // 32: vtctlservice.Vtctld.ForceCutOverSchemaMigration:input_type -> vtctldata.ForceCutOverSchemaMigrationRequest + 33, // 33: vtctlservice.Vtctld.GetBackups:input_type -> vtctldata.GetBackupsRequest + 34, // 34: vtctlservice.Vtctld.GetCellInfo:input_type -> vtctldata.GetCellInfoRequest + 35, // 35: vtctlservice.Vtctld.GetCellInfoNames:input_type -> vtctldata.GetCellInfoNamesRequest + 36, // 36: vtctlservice.Vtctld.GetCellsAliases:input_type -> vtctldata.GetCellsAliasesRequest + 37, // 37: vtctlservice.Vtctld.GetFullStatus:input_type -> vtctldata.GetFullStatusRequest + 38, // 38: vtctlservice.Vtctld.GetKeyspace:input_type -> vtctldata.GetKeyspaceRequest + 39, // 39: vtctlservice.Vtctld.GetKeyspaces:input_type -> vtctldata.GetKeyspacesRequest + 40, // 40: vtctlservice.Vtctld.GetKeyspaceRoutingRules:input_type -> vtctldata.GetKeyspaceRoutingRulesRequest + 41, // 41: vtctlservice.Vtctld.GetPermissions:input_type -> vtctldata.GetPermissionsRequest + 42, // 42: vtctlservice.Vtctld.GetRoutingRules:input_type -> vtctldata.GetRoutingRulesRequest + 43, // 43: vtctlservice.Vtctld.GetSchema:input_type -> vtctldata.GetSchemaRequest + 44, // 44: vtctlservice.Vtctld.GetSchemaMigrations:input_type -> vtctldata.GetSchemaMigrationsRequest + 45, // 45: vtctlservice.Vtctld.GetShardReplication:input_type -> vtctldata.GetShardReplicationRequest + 46, // 46: vtctlservice.Vtctld.GetShard:input_type -> vtctldata.GetShardRequest + 47, // 47: vtctlservice.Vtctld.GetShardRoutingRules:input_type -> vtctldata.GetShardRoutingRulesRequest + 48, // 48: vtctlservice.Vtctld.GetSrvKeyspaceNames:input_type -> vtctldata.GetSrvKeyspaceNamesRequest + 49, // 49: vtctlservice.Vtctld.GetSrvKeyspaces:input_type -> vtctldata.GetSrvKeyspacesRequest + 50, // 50: vtctlservice.Vtctld.UpdateThrottlerConfig:input_type -> vtctldata.UpdateThrottlerConfigRequest + 51, // 51: vtctlservice.Vtctld.GetSrvVSchema:input_type -> vtctldata.GetSrvVSchemaRequest + 52, // 52: vtctlservice.Vtctld.GetSrvVSchemas:input_type -> vtctldata.GetSrvVSchemasRequest + 53, // 53: vtctlservice.Vtctld.GetTablet:input_type -> vtctldata.GetTabletRequest + 54, // 54: vtctlservice.Vtctld.GetTablets:input_type -> vtctldata.GetTabletsRequest + 55, // 55: vtctlservice.Vtctld.GetThrottlerStatus:input_type -> vtctldata.GetThrottlerStatusRequest + 56, // 56: vtctlservice.Vtctld.GetTopologyPath:input_type -> vtctldata.GetTopologyPathRequest + 57, // 57: vtctlservice.Vtctld.GetTransactionInfo:input_type -> vtctldata.GetTransactionInfoRequest + 58, // 58: vtctlservice.Vtctld.GetUnresolvedTransactions:input_type -> vtctldata.GetUnresolvedTransactionsRequest + 59, // 59: vtctlservice.Vtctld.GetVersion:input_type -> vtctldata.GetVersionRequest + 60, // 60: vtctlservice.Vtctld.GetVSchema:input_type -> vtctldata.GetVSchemaRequest + 61, // 61: vtctlservice.Vtctld.GetWorkflows:input_type -> vtctldata.GetWorkflowsRequest + 62, // 62: vtctlservice.Vtctld.InitShardPrimary:input_type -> vtctldata.InitShardPrimaryRequest + 63, // 63: vtctlservice.Vtctld.LaunchSchemaMigration:input_type -> vtctldata.LaunchSchemaMigrationRequest + 64, // 64: vtctlservice.Vtctld.LookupVindexComplete:input_type -> vtctldata.LookupVindexCompleteRequest + 65, // 65: vtctlservice.Vtctld.LookupVindexCreate:input_type -> vtctldata.LookupVindexCreateRequest + 66, // 66: vtctlservice.Vtctld.LookupVindexExternalize:input_type -> vtctldata.LookupVindexExternalizeRequest + 67, // 67: vtctlservice.Vtctld.LookupVindexInternalize:input_type -> vtctldata.LookupVindexInternalizeRequest + 68, // 68: vtctlservice.Vtctld.MaterializeCreate:input_type -> vtctldata.MaterializeCreateRequest + 69, // 69: vtctlservice.Vtctld.MigrateCreate:input_type -> vtctldata.MigrateCreateRequest + 70, // 70: vtctlservice.Vtctld.MountRegister:input_type -> vtctldata.MountRegisterRequest + 71, // 71: vtctlservice.Vtctld.MountUnregister:input_type -> vtctldata.MountUnregisterRequest + 72, // 72: vtctlservice.Vtctld.MountShow:input_type -> vtctldata.MountShowRequest + 73, // 73: vtctlservice.Vtctld.MountList:input_type -> vtctldata.MountListRequest + 74, // 74: vtctlservice.Vtctld.MoveTablesCreate:input_type -> vtctldata.MoveTablesCreateRequest + 75, // 75: vtctlservice.Vtctld.MoveTablesComplete:input_type -> vtctldata.MoveTablesCompleteRequest + 76, // 76: vtctlservice.Vtctld.PingTablet:input_type -> vtctldata.PingTabletRequest + 77, // 77: vtctlservice.Vtctld.PlannedReparentShard:input_type -> vtctldata.PlannedReparentShardRequest + 78, // 78: vtctlservice.Vtctld.RebuildKeyspaceGraph:input_type -> vtctldata.RebuildKeyspaceGraphRequest + 79, // 79: vtctlservice.Vtctld.RebuildVSchemaGraph:input_type -> vtctldata.RebuildVSchemaGraphRequest + 80, // 80: vtctlservice.Vtctld.RefreshState:input_type -> vtctldata.RefreshStateRequest + 81, // 81: vtctlservice.Vtctld.RefreshStateByShard:input_type -> vtctldata.RefreshStateByShardRequest + 82, // 82: vtctlservice.Vtctld.ReloadSchema:input_type -> vtctldata.ReloadSchemaRequest + 83, // 83: vtctlservice.Vtctld.ReloadSchemaKeyspace:input_type -> vtctldata.ReloadSchemaKeyspaceRequest + 84, // 84: vtctlservice.Vtctld.ReloadSchemaShard:input_type -> vtctldata.ReloadSchemaShardRequest + 85, // 85: vtctlservice.Vtctld.RemoveBackup:input_type -> vtctldata.RemoveBackupRequest + 86, // 86: vtctlservice.Vtctld.RemoveKeyspaceCell:input_type -> vtctldata.RemoveKeyspaceCellRequest + 87, // 87: vtctlservice.Vtctld.RemoveShardCell:input_type -> vtctldata.RemoveShardCellRequest + 88, // 88: vtctlservice.Vtctld.ReparentTablet:input_type -> vtctldata.ReparentTabletRequest + 89, // 89: vtctlservice.Vtctld.ReshardCreate:input_type -> vtctldata.ReshardCreateRequest + 90, // 90: vtctlservice.Vtctld.RestoreFromBackup:input_type -> vtctldata.RestoreFromBackupRequest + 91, // 91: vtctlservice.Vtctld.RetrySchemaMigration:input_type -> vtctldata.RetrySchemaMigrationRequest + 92, // 92: vtctlservice.Vtctld.RunHealthCheck:input_type -> vtctldata.RunHealthCheckRequest + 93, // 93: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:input_type -> vtctldata.SetKeyspaceDurabilityPolicyRequest + 94, // 94: vtctlservice.Vtctld.SetShardIsPrimaryServing:input_type -> vtctldata.SetShardIsPrimaryServingRequest + 95, // 95: vtctlservice.Vtctld.SetShardTabletControl:input_type -> vtctldata.SetShardTabletControlRequest + 96, // 96: vtctlservice.Vtctld.SetWritable:input_type -> vtctldata.SetWritableRequest + 97, // 97: vtctlservice.Vtctld.ShardReplicationAdd:input_type -> vtctldata.ShardReplicationAddRequest + 98, // 98: vtctlservice.Vtctld.ShardReplicationFix:input_type -> vtctldata.ShardReplicationFixRequest + 99, // 99: vtctlservice.Vtctld.ShardReplicationPositions:input_type -> vtctldata.ShardReplicationPositionsRequest + 100, // 100: vtctlservice.Vtctld.ShardReplicationRemove:input_type -> vtctldata.ShardReplicationRemoveRequest + 101, // 101: vtctlservice.Vtctld.SleepTablet:input_type -> vtctldata.SleepTabletRequest + 102, // 102: vtctlservice.Vtctld.SourceShardAdd:input_type -> vtctldata.SourceShardAddRequest + 103, // 103: vtctlservice.Vtctld.SourceShardDelete:input_type -> vtctldata.SourceShardDeleteRequest + 104, // 104: vtctlservice.Vtctld.StartReplication:input_type -> vtctldata.StartReplicationRequest + 105, // 105: vtctlservice.Vtctld.StopReplication:input_type -> vtctldata.StopReplicationRequest + 106, // 106: vtctlservice.Vtctld.TabletExternallyReparented:input_type -> vtctldata.TabletExternallyReparentedRequest + 107, // 107: vtctlservice.Vtctld.UpdateCellInfo:input_type -> vtctldata.UpdateCellInfoRequest + 108, // 108: vtctlservice.Vtctld.UpdateCellsAlias:input_type -> vtctldata.UpdateCellsAliasRequest + 109, // 109: vtctlservice.Vtctld.Validate:input_type -> vtctldata.ValidateRequest + 110, // 110: vtctlservice.Vtctld.ValidateKeyspace:input_type -> vtctldata.ValidateKeyspaceRequest + 111, // 111: vtctlservice.Vtctld.ValidatePermissionsKeyspace:input_type -> vtctldata.ValidatePermissionsKeyspaceRequest + 112, // 112: vtctlservice.Vtctld.ValidateSchemaKeyspace:input_type -> vtctldata.ValidateSchemaKeyspaceRequest + 113, // 113: vtctlservice.Vtctld.ValidateShard:input_type -> vtctldata.ValidateShardRequest + 114, // 114: vtctlservice.Vtctld.ValidateVersionKeyspace:input_type -> vtctldata.ValidateVersionKeyspaceRequest + 115, // 115: vtctlservice.Vtctld.ValidateVersionShard:input_type -> vtctldata.ValidateVersionShardRequest + 116, // 116: vtctlservice.Vtctld.ValidateVSchema:input_type -> vtctldata.ValidateVSchemaRequest + 117, // 117: vtctlservice.Vtctld.VDiffCreate:input_type -> vtctldata.VDiffCreateRequest + 118, // 118: vtctlservice.Vtctld.VDiffDelete:input_type -> vtctldata.VDiffDeleteRequest + 119, // 119: vtctlservice.Vtctld.VDiffResume:input_type -> vtctldata.VDiffResumeRequest + 120, // 120: vtctlservice.Vtctld.VDiffShow:input_type -> vtctldata.VDiffShowRequest + 121, // 121: vtctlservice.Vtctld.VDiffStop:input_type -> vtctldata.VDiffStopRequest + 122, // 122: vtctlservice.Vtctld.WorkflowDelete:input_type -> vtctldata.WorkflowDeleteRequest + 123, // 123: vtctlservice.Vtctld.WorkflowStatus:input_type -> vtctldata.WorkflowStatusRequest + 124, // 124: vtctlservice.Vtctld.WorkflowSwitchTraffic:input_type -> vtctldata.WorkflowSwitchTrafficRequest + 125, // 125: vtctlservice.Vtctld.WorkflowUpdate:input_type -> vtctldata.WorkflowUpdateRequest + 126, // 126: vtctlservice.Vtctld.GetMirrorRules:input_type -> vtctldata.GetMirrorRulesRequest + 127, // 127: vtctlservice.Vtctld.WorkflowMirrorTraffic:input_type -> vtctldata.WorkflowMirrorTrafficRequest + 128, // 128: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse + 129, // 129: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse + 130, // 130: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse + 131, // 131: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse + 132, // 132: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse + 133, // 133: vtctlservice.Vtctld.ApplyKeyspaceRoutingRules:output_type -> vtctldata.ApplyKeyspaceRoutingRulesResponse + 134, // 134: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse + 135, // 135: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse + 136, // 136: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse + 136, // 137: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse + 137, // 138: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse + 138, // 139: vtctlservice.Vtctld.ChangeTabletTags:output_type -> vtctldata.ChangeTabletTagsResponse + 139, // 140: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse + 140, // 141: vtctlservice.Vtctld.CheckThrottler:output_type -> vtctldata.CheckThrottlerResponse + 141, // 142: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse + 142, // 143: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse + 143, // 144: vtctlservice.Vtctld.ConcludeTransaction:output_type -> vtctldata.ConcludeTransactionResponse + 144, // 145: vtctlservice.Vtctld.CopySchemaShard:output_type -> vtctldata.CopySchemaShardResponse + 145, // 146: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse + 146, // 147: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse + 147, // 148: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse + 148, // 149: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse + 149, // 150: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse + 150, // 151: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse + 151, // 152: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse + 152, // 153: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse + 153, // 154: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse + 154, // 155: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse + 155, // 156: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse + 156, // 157: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse + 157, // 158: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:output_type -> vtctldata.ExecuteMultiFetchAsDBAResponse + 158, // 159: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse + 159, // 160: vtctlservice.Vtctld.ForceCutOverSchemaMigration:output_type -> vtctldata.ForceCutOverSchemaMigrationResponse + 160, // 161: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse + 161, // 162: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse + 162, // 163: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse + 163, // 164: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse + 164, // 165: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse + 165, // 166: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse + 166, // 167: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse + 167, // 168: vtctlservice.Vtctld.GetKeyspaceRoutingRules:output_type -> vtctldata.GetKeyspaceRoutingRulesResponse + 168, // 169: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse + 169, // 170: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse + 170, // 171: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse + 171, // 172: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse + 172, // 173: vtctlservice.Vtctld.GetShardReplication:output_type -> vtctldata.GetShardReplicationResponse + 173, // 174: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse + 174, // 175: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse + 175, // 176: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse + 176, // 177: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse + 177, // 178: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse + 178, // 179: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse + 179, // 180: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse + 180, // 181: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse + 181, // 182: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse + 182, // 183: vtctlservice.Vtctld.GetThrottlerStatus:output_type -> vtctldata.GetThrottlerStatusResponse + 183, // 184: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse + 184, // 185: vtctlservice.Vtctld.GetTransactionInfo:output_type -> vtctldata.GetTransactionInfoResponse + 185, // 186: vtctlservice.Vtctld.GetUnresolvedTransactions:output_type -> vtctldata.GetUnresolvedTransactionsResponse + 186, // 187: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse + 187, // 188: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse + 188, // 189: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse + 189, // 190: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse + 190, // 191: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse + 191, // 192: vtctlservice.Vtctld.LookupVindexComplete:output_type -> vtctldata.LookupVindexCompleteResponse + 192, // 193: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse + 193, // 194: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse + 194, // 195: vtctlservice.Vtctld.LookupVindexInternalize:output_type -> vtctldata.LookupVindexInternalizeResponse + 195, // 196: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse + 196, // 197: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse + 197, // 198: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse + 198, // 199: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse + 199, // 200: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse + 200, // 201: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse + 196, // 202: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse + 201, // 203: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse + 202, // 204: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse + 203, // 205: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse + 204, // 206: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse + 205, // 207: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse + 206, // 208: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse + 207, // 209: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse + 208, // 210: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse + 209, // 211: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse + 210, // 212: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse + 211, // 213: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse + 212, // 214: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse + 213, // 215: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse + 214, // 216: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse + 196, // 217: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse + 215, // 218: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse + 216, // 219: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse + 217, // 220: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse + 218, // 221: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse + 219, // 222: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse + 220, // 223: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse + 221, // 224: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse + 222, // 225: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse + 223, // 226: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse + 224, // 227: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse + 225, // 228: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse + 226, // 229: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse + 227, // 230: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse + 228, // 231: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse + 229, // 232: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse + 230, // 233: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse + 231, // 234: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse + 232, // 235: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse + 233, // 236: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse + 234, // 237: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse + 235, // 238: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse + 236, // 239: vtctlservice.Vtctld.ValidatePermissionsKeyspace:output_type -> vtctldata.ValidatePermissionsKeyspaceResponse + 237, // 240: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse + 238, // 241: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse + 239, // 242: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse + 240, // 243: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse + 241, // 244: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse + 242, // 245: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse + 243, // 246: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse + 244, // 247: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse + 245, // 248: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse + 246, // 249: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse + 247, // 250: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse + 196, // 251: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse + 248, // 252: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse + 249, // 253: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse + 250, // 254: vtctlservice.Vtctld.GetMirrorRules:output_type -> vtctldata.GetMirrorRulesResponse + 251, // 255: vtctlservice.Vtctld.WorkflowMirrorTraffic:output_type -> vtctldata.WorkflowMirrorTrafficResponse + 128, // [128:256] is the sub-list for method output_type + 0, // [0:128] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go index 0b2e5bae7dc..e906754620f 100644 --- a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go @@ -179,6 +179,8 @@ type VtctldClient interface { CompleteSchemaMigration(ctx context.Context, in *vtctldata.CompleteSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldata.CompleteSchemaMigrationResponse, error) // CompleteSchemaMigration completes one or all migrations executed with --postpone-completion. ConcludeTransaction(ctx context.Context, in *vtctldata.ConcludeTransactionRequest, opts ...grpc.CallOption) (*vtctldata.ConcludeTransactionResponse, error) + // CopySchemaShard copies the schema from a source tablet to all tablets in a keyspace/shard. + CopySchemaShard(ctx context.Context, in *vtctldata.CopySchemaShardRequest, opts ...grpc.CallOption) (*vtctldata.CopySchemaShardResponse, error) // CreateKeyspace creates the specified keyspace in the topology. For a // SNAPSHOT keyspace, the request must specify the name of a base keyspace, // as well as a snapshot time. @@ -297,8 +299,10 @@ type VtctldClient interface { InitShardPrimary(ctx context.Context, in *vtctldata.InitShardPrimaryRequest, opts ...grpc.CallOption) (*vtctldata.InitShardPrimaryResponse, error) // LaunchSchemaMigration launches one or all migrations executed with --postpone-launch. LaunchSchemaMigration(ctx context.Context, in *vtctldata.LaunchSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldata.LaunchSchemaMigrationResponse, error) + LookupVindexComplete(ctx context.Context, in *vtctldata.LookupVindexCompleteRequest, opts ...grpc.CallOption) (*vtctldata.LookupVindexCompleteResponse, error) LookupVindexCreate(ctx context.Context, in *vtctldata.LookupVindexCreateRequest, opts ...grpc.CallOption) (*vtctldata.LookupVindexCreateResponse, error) LookupVindexExternalize(ctx context.Context, in *vtctldata.LookupVindexExternalizeRequest, opts ...grpc.CallOption) (*vtctldata.LookupVindexExternalizeResponse, error) + LookupVindexInternalize(ctx context.Context, in *vtctldata.LookupVindexInternalizeRequest, opts ...grpc.CallOption) (*vtctldata.LookupVindexInternalizeResponse, error) // MaterializeCreate creates a workflow to materialize one or more tables // from a source keyspace to a target keyspace using a provided expressions. MaterializeCreate(ctx context.Context, in *vtctldata.MaterializeCreateRequest, opts ...grpc.CallOption) (*vtctldata.MaterializeCreateResponse, error) @@ -449,6 +453,8 @@ type VtctldClient interface { // ValidateKeyspace validates that all nodes reachable from the specified // keyspace are consistent. ValidateKeyspace(ctx context.Context, in *vtctldata.ValidateKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.ValidateKeyspaceResponse, error) + // ValidatePermissionsKeyspace validates that all the permissions are the same in a keyspace. + ValidatePermissionsKeyspace(ctx context.Context, in *vtctldata.ValidatePermissionsKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.ValidatePermissionsKeyspaceResponse, error) // ValidateSchemaKeyspace validates that the schema on the primary tablet for shard 0 matches the schema on all of the other tablets in the keyspace. ValidateSchemaKeyspace(ctx context.Context, in *vtctldata.ValidateSchemaKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.ValidateSchemaKeyspaceResponse, error) // ValidateShard validates that all nodes reachable from the specified shard @@ -675,6 +681,15 @@ func (c *vtctldClient) ConcludeTransaction(ctx context.Context, in *vtctldata.Co return out, nil } +func (c *vtctldClient) CopySchemaShard(ctx context.Context, in *vtctldata.CopySchemaShardRequest, opts ...grpc.CallOption) (*vtctldata.CopySchemaShardResponse, error) { + out := new(vtctldata.CopySchemaShardResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/CopySchemaShard", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) CreateKeyspace(ctx context.Context, in *vtctldata.CreateKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.CreateKeyspaceResponse, error) { out := new(vtctldata.CreateKeyspaceResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/CreateKeyspace", in, out, opts...) @@ -1089,6 +1104,15 @@ func (c *vtctldClient) LaunchSchemaMigration(ctx context.Context, in *vtctldata. return out, nil } +func (c *vtctldClient) LookupVindexComplete(ctx context.Context, in *vtctldata.LookupVindexCompleteRequest, opts ...grpc.CallOption) (*vtctldata.LookupVindexCompleteResponse, error) { + out := new(vtctldata.LookupVindexCompleteResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/LookupVindexComplete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) LookupVindexCreate(ctx context.Context, in *vtctldata.LookupVindexCreateRequest, opts ...grpc.CallOption) (*vtctldata.LookupVindexCreateResponse, error) { out := new(vtctldata.LookupVindexCreateResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/LookupVindexCreate", in, out, opts...) @@ -1107,6 +1131,15 @@ func (c *vtctldClient) LookupVindexExternalize(ctx context.Context, in *vtctldat return out, nil } +func (c *vtctldClient) LookupVindexInternalize(ctx context.Context, in *vtctldata.LookupVindexInternalizeRequest, opts ...grpc.CallOption) (*vtctldata.LookupVindexInternalizeResponse, error) { + out := new(vtctldata.LookupVindexInternalizeResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/LookupVindexInternalize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) MaterializeCreate(ctx context.Context, in *vtctldata.MaterializeCreateRequest, opts ...grpc.CallOption) (*vtctldata.MaterializeCreateResponse, error) { out := new(vtctldata.MaterializeCreateResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/MaterializeCreate", in, out, opts...) @@ -1517,6 +1550,15 @@ func (c *vtctldClient) ValidateKeyspace(ctx context.Context, in *vtctldata.Valid return out, nil } +func (c *vtctldClient) ValidatePermissionsKeyspace(ctx context.Context, in *vtctldata.ValidatePermissionsKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.ValidatePermissionsKeyspaceResponse, error) { + out := new(vtctldata.ValidatePermissionsKeyspaceResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/ValidatePermissionsKeyspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) ValidateSchemaKeyspace(ctx context.Context, in *vtctldata.ValidateSchemaKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.ValidateSchemaKeyspaceResponse, error) { out := new(vtctldata.ValidateSchemaKeyspaceResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/ValidateSchemaKeyspace", in, out, opts...) @@ -1708,6 +1750,8 @@ type VtctldServer interface { CompleteSchemaMigration(context.Context, *vtctldata.CompleteSchemaMigrationRequest) (*vtctldata.CompleteSchemaMigrationResponse, error) // CompleteSchemaMigration completes one or all migrations executed with --postpone-completion. ConcludeTransaction(context.Context, *vtctldata.ConcludeTransactionRequest) (*vtctldata.ConcludeTransactionResponse, error) + // CopySchemaShard copies the schema from a source tablet to all tablets in a keyspace/shard. + CopySchemaShard(context.Context, *vtctldata.CopySchemaShardRequest) (*vtctldata.CopySchemaShardResponse, error) // CreateKeyspace creates the specified keyspace in the topology. For a // SNAPSHOT keyspace, the request must specify the name of a base keyspace, // as well as a snapshot time. @@ -1826,8 +1870,10 @@ type VtctldServer interface { InitShardPrimary(context.Context, *vtctldata.InitShardPrimaryRequest) (*vtctldata.InitShardPrimaryResponse, error) // LaunchSchemaMigration launches one or all migrations executed with --postpone-launch. LaunchSchemaMigration(context.Context, *vtctldata.LaunchSchemaMigrationRequest) (*vtctldata.LaunchSchemaMigrationResponse, error) + LookupVindexComplete(context.Context, *vtctldata.LookupVindexCompleteRequest) (*vtctldata.LookupVindexCompleteResponse, error) LookupVindexCreate(context.Context, *vtctldata.LookupVindexCreateRequest) (*vtctldata.LookupVindexCreateResponse, error) LookupVindexExternalize(context.Context, *vtctldata.LookupVindexExternalizeRequest) (*vtctldata.LookupVindexExternalizeResponse, error) + LookupVindexInternalize(context.Context, *vtctldata.LookupVindexInternalizeRequest) (*vtctldata.LookupVindexInternalizeResponse, error) // MaterializeCreate creates a workflow to materialize one or more tables // from a source keyspace to a target keyspace using a provided expressions. MaterializeCreate(context.Context, *vtctldata.MaterializeCreateRequest) (*vtctldata.MaterializeCreateResponse, error) @@ -1978,6 +2024,8 @@ type VtctldServer interface { // ValidateKeyspace validates that all nodes reachable from the specified // keyspace are consistent. ValidateKeyspace(context.Context, *vtctldata.ValidateKeyspaceRequest) (*vtctldata.ValidateKeyspaceResponse, error) + // ValidatePermissionsKeyspace validates that all the permissions are the same in a keyspace. + ValidatePermissionsKeyspace(context.Context, *vtctldata.ValidatePermissionsKeyspaceRequest) (*vtctldata.ValidatePermissionsKeyspaceResponse, error) // ValidateSchemaKeyspace validates that the schema on the primary tablet for shard 0 matches the schema on all of the other tablets in the keyspace. ValidateSchemaKeyspace(context.Context, *vtctldata.ValidateSchemaKeyspaceRequest) (*vtctldata.ValidateSchemaKeyspaceResponse, error) // ValidateShard validates that all nodes reachable from the specified shard @@ -2059,6 +2107,9 @@ func (UnimplementedVtctldServer) CompleteSchemaMigration(context.Context, *vtctl func (UnimplementedVtctldServer) ConcludeTransaction(context.Context, *vtctldata.ConcludeTransactionRequest) (*vtctldata.ConcludeTransactionResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ConcludeTransaction not implemented") } +func (UnimplementedVtctldServer) CopySchemaShard(context.Context, *vtctldata.CopySchemaShardRequest) (*vtctldata.CopySchemaShardResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CopySchemaShard not implemented") +} func (UnimplementedVtctldServer) CreateKeyspace(context.Context, *vtctldata.CreateKeyspaceRequest) (*vtctldata.CreateKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateKeyspace not implemented") } @@ -2197,12 +2248,18 @@ func (UnimplementedVtctldServer) InitShardPrimary(context.Context, *vtctldata.In func (UnimplementedVtctldServer) LaunchSchemaMigration(context.Context, *vtctldata.LaunchSchemaMigrationRequest) (*vtctldata.LaunchSchemaMigrationResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method LaunchSchemaMigration not implemented") } +func (UnimplementedVtctldServer) LookupVindexComplete(context.Context, *vtctldata.LookupVindexCompleteRequest) (*vtctldata.LookupVindexCompleteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LookupVindexComplete not implemented") +} func (UnimplementedVtctldServer) LookupVindexCreate(context.Context, *vtctldata.LookupVindexCreateRequest) (*vtctldata.LookupVindexCreateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method LookupVindexCreate not implemented") } func (UnimplementedVtctldServer) LookupVindexExternalize(context.Context, *vtctldata.LookupVindexExternalizeRequest) (*vtctldata.LookupVindexExternalizeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method LookupVindexExternalize not implemented") } +func (UnimplementedVtctldServer) LookupVindexInternalize(context.Context, *vtctldata.LookupVindexInternalizeRequest) (*vtctldata.LookupVindexInternalizeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LookupVindexInternalize not implemented") +} func (UnimplementedVtctldServer) MaterializeCreate(context.Context, *vtctldata.MaterializeCreateRequest) (*vtctldata.MaterializeCreateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method MaterializeCreate not implemented") } @@ -2332,6 +2389,9 @@ func (UnimplementedVtctldServer) Validate(context.Context, *vtctldata.ValidateRe func (UnimplementedVtctldServer) ValidateKeyspace(context.Context, *vtctldata.ValidateKeyspaceRequest) (*vtctldata.ValidateKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ValidateKeyspace not implemented") } +func (UnimplementedVtctldServer) ValidatePermissionsKeyspace(context.Context, *vtctldata.ValidatePermissionsKeyspaceRequest) (*vtctldata.ValidatePermissionsKeyspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidatePermissionsKeyspace not implemented") +} func (UnimplementedVtctldServer) ValidateSchemaKeyspace(context.Context, *vtctldata.ValidateSchemaKeyspaceRequest) (*vtctldata.ValidateSchemaKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ValidateSchemaKeyspace not implemented") } @@ -2687,6 +2747,24 @@ func _Vtctld_ConcludeTransaction_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Vtctld_CopySchemaShard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.CopySchemaShardRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).CopySchemaShard(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/CopySchemaShard", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).CopySchemaShard(ctx, req.(*vtctldata.CopySchemaShardRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_CreateKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.CreateKeyspaceRequest) if err := dec(in); err != nil { @@ -3515,6 +3593,24 @@ func _Vtctld_LaunchSchemaMigration_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Vtctld_LookupVindexComplete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.LookupVindexCompleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).LookupVindexComplete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/LookupVindexComplete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).LookupVindexComplete(ctx, req.(*vtctldata.LookupVindexCompleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_LookupVindexCreate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.LookupVindexCreateRequest) if err := dec(in); err != nil { @@ -3551,6 +3647,24 @@ func _Vtctld_LookupVindexExternalize_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _Vtctld_LookupVindexInternalize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.LookupVindexInternalizeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).LookupVindexInternalize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/LookupVindexInternalize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).LookupVindexInternalize(ctx, req.(*vtctldata.LookupVindexInternalizeRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_MaterializeCreate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.MaterializeCreateRequest) if err := dec(in); err != nil { @@ -4328,6 +4442,24 @@ func _Vtctld_ValidateKeyspace_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Vtctld_ValidatePermissionsKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.ValidatePermissionsKeyspaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).ValidatePermissionsKeyspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/ValidatePermissionsKeyspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).ValidatePermissionsKeyspace(ctx, req.(*vtctldata.ValidatePermissionsKeyspaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_ValidateSchemaKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.ValidateSchemaKeyspaceRequest) if err := dec(in); err != nil { @@ -4679,6 +4811,10 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "ConcludeTransaction", Handler: _Vtctld_ConcludeTransaction_Handler, }, + { + MethodName: "CopySchemaShard", + Handler: _Vtctld_CopySchemaShard_Handler, + }, { MethodName: "CreateKeyspace", Handler: _Vtctld_CreateKeyspace_Handler, @@ -4863,6 +4999,10 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "LaunchSchemaMigration", Handler: _Vtctld_LaunchSchemaMigration_Handler, }, + { + MethodName: "LookupVindexComplete", + Handler: _Vtctld_LookupVindexComplete_Handler, + }, { MethodName: "LookupVindexCreate", Handler: _Vtctld_LookupVindexCreate_Handler, @@ -4871,6 +5011,10 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "LookupVindexExternalize", Handler: _Vtctld_LookupVindexExternalize_Handler, }, + { + MethodName: "LookupVindexInternalize", + Handler: _Vtctld_LookupVindexInternalize_Handler, + }, { MethodName: "MaterializeCreate", Handler: _Vtctld_MaterializeCreate_Handler, @@ -5039,6 +5183,10 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "ValidateKeyspace", Handler: _Vtctld_ValidateKeyspace_Handler, }, + { + MethodName: "ValidatePermissionsKeyspace", + Handler: _Vtctld_ValidatePermissionsKeyspace_Handler, + }, { MethodName: "ValidateSchemaKeyspace", Handler: _Vtctld_ValidateSchemaKeyspace_Handler, diff --git a/go/vt/proto/vttime/cached_size.go b/go/vt/proto/vttime/cached_size.go index 62a6366ba3c..f2b69dbefae 100644 --- a/go/vt/proto/vttime/cached_size.go +++ b/go/vt/proto/vttime/cached_size.go @@ -17,6 +17,8 @@ limitations under the License. package vttime +import hack "vitess.io/vitess/go/hack" + func (cached *Time) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -25,5 +27,9 @@ func (cached *Time) CachedSize(alloc bool) int64 { if alloc { size += int64(64) } + // field unknownFields google.golang.org/protobuf/runtime/protoimpl.UnknownFields + { + size += hack.RuntimeAllocSize(int64(cap(cached.unknownFields))) + } return size } diff --git a/go/vt/schema/cached_size.go b/go/vt/schema/cached_size.go index a2ea8f55deb..5ed67c01696 100644 --- a/go/vt/schema/cached_size.go +++ b/go/vt/schema/cached_size.go @@ -19,6 +19,17 @@ package schema import hack "vitess.io/vitess/go/hack" +func (cached *DDLStrategy) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += hack.RuntimeAllocSize(int64(16)) + } + size += hack.RuntimeAllocSize(int64(len(*cached))) + return size +} func (cached *DDLStrategySetting) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/schemadiff/errors.go b/go/vt/schemadiff/errors.go index c938e736206..74d1c231a19 100644 --- a/go/vt/schemadiff/errors.go +++ b/go/vt/schemadiff/errors.go @@ -497,3 +497,21 @@ type NonDeterministicDefaultError struct { func (e *NonDeterministicDefaultError) Error() string { return fmt.Sprintf("column %s.%s default value uses non-deterministic function: %s", sqlescape.EscapeID(e.Table), sqlescape.EscapeID(e.Column), e.Function) } + +type DuplicateCheckConstraintNameError struct { + Table string + Constraint string +} + +func (e *DuplicateCheckConstraintNameError) Error() string { + return fmt.Sprintf("duplicate check constraint name %s in table %s", sqlescape.EscapeID(e.Constraint), sqlescape.EscapeID(e.Table)) +} + +type DuplicateForeignKeyConstraintNameError struct { + Table string + Constraint string +} + +func (e *DuplicateForeignKeyConstraintNameError) Error() string { + return fmt.Sprintf("duplicate foreign key constraint name %s in table %s", sqlescape.EscapeID(e.Constraint), sqlescape.EscapeID(e.Table)) +} diff --git a/go/vt/schemadiff/key.go b/go/vt/schemadiff/key.go index 865073a5a98..97f3af1630c 100644 --- a/go/vt/schemadiff/key.go +++ b/go/vt/schemadiff/key.go @@ -68,6 +68,16 @@ func (i *IndexDefinitionEntity) IsUnique() bool { return i.IndexDefinition.Info.IsUnique() } +// HasExpression returns true if the index uses an expression, e.g. `KEY idx1 ((id + 1))`. +func (i *IndexDefinitionEntity) HasExpression() bool { + for _, col := range i.IndexDefinition.Columns { + if col.Expression != nil { + return true + } + } + return false +} + // HasNullable returns true if any of the columns in the index are nullable. func (i *IndexDefinitionEntity) HasNullable() bool { for _, col := range i.ColumnList.Entities { diff --git a/go/vt/schemadiff/onlineddl.go b/go/vt/schemadiff/onlineddl.go index f02ccb1224d..06f3384c8fd 100644 --- a/go/vt/schemadiff/onlineddl.go +++ b/go/vt/schemadiff/onlineddl.go @@ -162,6 +162,11 @@ func PrioritizedUniqueKeys(createTableEntity *CreateTableEntity) *IndexDefinitio if !key.IsUnique() { continue } + if key.HasExpression() { + // If the key has an expression this means it unreliably covers the columns, + // we cannot trust it. + continue + } uniqueKeys = append(uniqueKeys, key) } sort.SliceStable(uniqueKeys, func(i, j int) bool { diff --git a/go/vt/schemadiff/onlineddl_test.go b/go/vt/schemadiff/onlineddl_test.go index 834490dca1b..fb8710f8498 100644 --- a/go/vt/schemadiff/onlineddl_test.go +++ b/go/vt/schemadiff/onlineddl_test.go @@ -932,6 +932,16 @@ func TestRevertible(t *testing.T) { toSchema: `id int primary key, e1 set('a', 'b'), e2 set('a'), e3 set('a', 'b', 'c'), e4 set('a', 'x'), e5 set('a', 'x', 'b'), e6 set('b'), e7 varchar(1), e8 tinyint`, expandedColumnNames: `e3,e4,e5,e6,e7,e8`, }, + { + name: "index with expression", + fromSchema: "id int, primary key (id), key idx1 ((id + 1))", + toSchema: "id int, primary key (id), key idx2 ((id + 2))", + }, + { + name: "remove unique index with expression, add another, skip both", + fromSchema: "id int, i int, primary key (id), unique key idx1 ((id + 1))", + toSchema: "id int, i int, primary key (id), unique key idx2 ((i + 2))", + }, } var ( diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 3b42d6cf42d..bbd1258070e 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -415,6 +415,27 @@ func (s *Schema) normalize(hints *DiffHints) error { } } } + + // Validate uniqueness of check constraint and of foreign key constraint names + fkConstraintNames := map[string]bool{} + checkConstraintNames := map[string]bool{} + for _, t := range s.tables { + for _, cs := range t.TableSpec.Constraints { + if _, ok := cs.Details.(*sqlparser.ForeignKeyDefinition); ok { + if _, ok := fkConstraintNames[cs.Name.String()]; ok { + errs = errors.Join(errs, &DuplicateForeignKeyConstraintNameError{Table: t.Name(), Constraint: cs.Name.String()}) + } + fkConstraintNames[cs.Name.String()] = true + } + if _, ok := cs.Details.(*sqlparser.CheckConstraintDefinition); ok { + if _, ok := checkConstraintNames[cs.Name.String()]; ok { + errs = errors.Join(errs, &DuplicateCheckConstraintNameError{Table: t.Name(), Constraint: cs.Name.String()}) + } + checkConstraintNames[cs.Name.String()] = true + } + } + } + return errs } diff --git a/go/vt/schemadiff/schema_diff_test.go b/go/vt/schemadiff/schema_diff_test.go index b39166451b2..70bdd9ed54b 100644 --- a/go/vt/schemadiff/schema_diff_test.go +++ b/go/vt/schemadiff/schema_diff_test.go @@ -1327,6 +1327,10 @@ func TestSchemaDiff(t *testing.T) { // TestDiffFiles diffs two schema files on the local file system. It requires the $TEST_SCHEMADIFF_DIFF_FILES // environment variable to be set to a comma-separated list of two file paths, e.g. "/tmp/from.sql,/tmp/to.sql". // If the variable is unspecified, the test is skipped. It is useful for ad-hoc testing of schema diffs. +// The way to run this test is: +// ```sh +// $ TEST_SCHEMADIFF_DIFF_FILES=/tmp/1.sql,/tmp/2.sql go test -v -count=1 -run TestDiffFiles ./go/vt/schemadiff/ +// ``` func TestDiffFiles(t *testing.T) { ctx := context.Background() diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 8a4f54269cd..1710cec12c7 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -287,11 +287,11 @@ func TestTableForeignKeyOrdering(t *testing.T) { "create table t11 (id int primary key, i int, key ix (i), constraint f12 foreign key (i) references t12(id) on delete restrict, constraint f20 foreign key (i) references t20(id) on delete restrict)", "create table t15(id int, primary key(id))", "create view v09 as select * from v13, t17", - "create table t20 (id int primary key, i int, key ix (i), constraint f15 foreign key (i) references t15(id) on delete restrict)", + "create table t20 (id int primary key, i int, key ix (i), constraint f2015 foreign key (i) references t15(id) on delete restrict)", "create view v13 as select * from t20", - "create table t12 (id int primary key, i int, key ix (i), constraint f15 foreign key (i) references t15(id) on delete restrict)", - "create table t17 (id int primary key, i int, key ix (i), constraint f11 foreign key (i) references t11(id) on delete restrict, constraint f15 foreign key (i) references t15(id) on delete restrict)", - "create table t16 (id int primary key, i int, key ix (i), constraint f11 foreign key (i) references t11(id) on delete restrict, constraint f15 foreign key (i) references t15(id) on delete restrict)", + "create table t12 (id int primary key, i int, key ix (i), constraint f1215 foreign key (i) references t15(id) on delete restrict)", + "create table t17 (id int primary key, i int, key ix (i), constraint f1711 foreign key (i) references t11(id) on delete restrict, constraint f1715 foreign key (i) references t15(id) on delete restrict)", + "create table t16 (id int primary key, i int, key ix (i), constraint f1611 foreign key (i) references t11(id) on delete restrict, constraint f1615 foreign key (i) references t15(id) on delete restrict)", "create table t14 (id int primary key, i int, key ix (i), constraint f14 foreign key (i) references t14(id) on delete restrict)", } expectSortedTableNames := []string{ @@ -522,6 +522,54 @@ func TestInvalidSchema(t *testing.T) { { 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;", }, + // constaint names + { + schema: `create table t1 (id int primary key, CONSTRAINT const_id CHECK (id > 0))`, + }, + { + schema: `create table t1 (id int primary key, CONSTRAINT const_id1 CHECK (id > 0), CONSTRAINT const_id2 CHECK (id < 10));`, + }, + { + schema: ` + create table t1 (id int primary key, CONSTRAINT const_id CHECK (id > 0), CONSTRAINT const_id CHECK (id < 10)); + `, + expectErr: &DuplicateCheckConstraintNameError{Table: "t1", Constraint: "const_id"}, + }, + { + schema: ` + create table t1 (id int primary key, CONSTRAINT const_id1 CHECK (id > 0)); + create table t2 (id int primary key, CONSTRAINT const_id2 CHECK (id > 0)); + `, + }, + { + schema: ` + create table t1 (id int primary key, CONSTRAINT const_id CHECK (id > 0)); + create table t2 (id int primary key, CONSTRAINT const_id CHECK (id > 0)); + `, + expectErr: &DuplicateCheckConstraintNameError{Table: "t2", Constraint: "const_id"}, + }, + { + // OK for foreign key constraint and check constraint to have same name + schema: ` + create table t1 (id int primary key, CONSTRAINT const_id CHECK (id > 0)); + create table t2 (id int primary key, CONSTRAINT const_id FOREIGN KEY (id) REFERENCES t1 (id) ON DELETE CASCADE); + `, + }, + { + schema: ` + create table t1 (id int primary key, CONSTRAINT const_id CHECK (id > 0)); + create table t2 (id int primary key, CONSTRAINT const_id FOREIGN KEY (id) REFERENCES t1 (id) ON DELETE CASCADE); + create table t3 (id int primary key, CONSTRAINT const_id FOREIGN KEY (id) REFERENCES t1 (id) ON DELETE CASCADE); + `, + expectErr: &DuplicateForeignKeyConstraintNameError{Table: "t3", Constraint: "const_id"}, + }, + { + schema: ` + create table t1 (id int primary key, CONSTRAINT const_id CHECK (id > 0)); + create table t2 (id int primary key, CONSTRAINT const_id FOREIGN KEY (id) REFERENCES t1 (id) ON DELETE CASCADE, CONSTRAINT const_id FOREIGN KEY (id) REFERENCES t1 (id) ON DELETE CASCADE); + `, + expectErr: &DuplicateForeignKeyConstraintNameError{Table: "t2", Constraint: "const_id"}, + }, } for _, ts := range tt { t.Run(ts.schema, func(t *testing.T) { diff --git a/go/vt/schemadiff/table.go b/go/vt/schemadiff/table.go index e002ef18e15..e9bb35cb3bd 100644 --- a/go/vt/schemadiff/table.go +++ b/go/vt/schemadiff/table.go @@ -500,9 +500,14 @@ func (c *CreateTableEntity) IndexDefinitionEntities() []*IndexDefinitionEntity { keys := c.CreateTable.TableSpec.Indexes entities := make([]*IndexDefinitionEntity, len(keys)) for i, key := range keys { - colEntities := make([]*ColumnDefinitionEntity, len(key.Columns)) - for i, keyCol := range key.Columns { - colEntities[i] = colMap[keyCol.Column.Lowered()] + colEntities := []*ColumnDefinitionEntity{} + for _, keyCol := range key.Columns { + colEntity, ok := colMap[keyCol.Column.Lowered()] + if !ok { + // This can happen if the index is on an expression, e.g. `KEY idx1 ((id + 1))`. + continue + } + colEntities = append(colEntities, colEntity) } entities[i] = NewIndexDefinitionEntity(c.Env, key, NewColumnDefinitionEntityList(colEntities)) } diff --git a/go/vt/schemadiff/table_test.go b/go/vt/schemadiff/table_test.go index 84c40d769c2..c1d8d8c241e 100644 --- a/go/vt/schemadiff/table_test.go +++ b/go/vt/schemadiff/table_test.go @@ -891,6 +891,18 @@ func TestCreateTableDiff(t *testing.T) { "+ KEY `i_idx` (`i`) INVISIBLE", }, }, + { + name: "keys with expression", + from: "create table t1 (id int, primary key (id), key idx1 ((id + 1)))", + to: "create table t1 (id int, primary key (id), key idx2 ((id + 2)))", + diff: "alter table t1 drop key idx1, add key idx2 ((id + 2))", + cdiff: "ALTER TABLE `t1` DROP KEY `idx1`, ADD KEY `idx2` ((`id` + 2))", + textdiffs: []string{ + "- KEY `idx1` ((`id` + 1))", + "+ KEY `idx2` ((`id` + 2))", + }, + }, + // FULLTEXT keys { name: "add one fulltext key", @@ -2564,6 +2576,30 @@ func TestValidate(t *testing.T) { alter: "alter table t engine=innodb", expectErr: &DuplicateKeyNameError{Table: "t", Key: "PRIMARY"}, }, + { + name: "key with expression", + from: "create table t (id int, primary key (id), key idx1 ((id + 1)))", + alter: "alter table t add key idx2 ((id + 2))", + to: "create table t (id int, primary key (id), key idx1 ((id + 1)), key idx2 ((id + 2)))", + }, + { + name: "key with multicolumn expression", + from: "create table t (id int, i int, primary key (id), key idx1 ((id + 1), (i + 2)))", + alter: "alter table t add key idx2 ((id + 2))", + to: "create table t (id int, i int, primary key (id), key idx1 ((id + 1), (i + 2)), key idx2 ((id + 2)))", + }, + { + name: "key with expression and unknown columns", + from: "create table t (id int, i int, primary key (id), key idx1 ((id + 1), (i + 2)))", + alter: "alter table t add key idx2 ((i2 + 2))", + expectErr: &InvalidColumnInKeyError{Table: "t", Column: "i2", Key: "idx2"}, + }, + { + name: "drop column used in expression", + from: "create table t (id int, i int, primary key (id), key idx1 ((id + 1), (i + 2)))", + alter: "alter table t drop column i", + expectErr: &InvalidColumnInKeyError{Table: "t", Column: "i", Key: "idx1"}, + }, // partitions { name: "drop column used by partitions", diff --git a/go/vt/schemadiff/view.go b/go/vt/schemadiff/view.go index 8783f1803bb..ff34d772dcf 100644 --- a/go/vt/schemadiff/view.go +++ b/go/vt/schemadiff/view.go @@ -427,6 +427,6 @@ func (c *CreateViewEntity) identicalOtherThanName(other *CreateViewEntity) bool c.IsReplace == other.IsReplace && sqlparser.Equals.RefOfDefiner(c.Definer, other.Definer) && sqlparser.Equals.Columns(c.Columns, other.Columns) && - sqlparser.Equals.SelectStatement(c.Select, other.Select) && + sqlparser.Equals.Statement(c.Select, other.Select) && sqlparser.Equals.RefOfParsedComments(c.Comments, other.Comments) } diff --git a/go/vt/servenv/buildinfo_test.go b/go/vt/servenv/buildinfo_test.go index bc972df03ea..a4a63cdb560 100644 --- a/go/vt/servenv/buildinfo_test.go +++ b/go/vt/servenv/buildinfo_test.go @@ -45,7 +45,7 @@ func TestVersionString(t *testing.T) { assert.Equal(t, "Version: v1.2.3-SNAPSHOT (Jenkins build 422) (Git revision d54b87ca0be09b678bb4490060e8f23f890ddb92 branch 'gitBranch') built on time is now by user@host using 1.20.2 amiga/amd64", v.String()) - assert.Equal(t, "8.0.30-Vitess", v.MySQLVersion()) + assert.Equal(t, "8.0.40-Vitess", v.MySQLVersion()) } func TestBuildVersionStats(t *testing.T) { diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 92c67d55999..e673b1ebf74 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -57,6 +57,34 @@ type ( OrderAndLimit interface { AddOrder(*Order) SetLimit(*Limit) + GetOrderBy() OrderBy + SetOrderBy(OrderBy) + GetLimit() *Limit + } + + TableStatement interface { + iTableStatement() + + InsertRows + Statement + OrderAndLimit + Commented + ColumnResults + Withable + } + + ColumnResults interface { + GetColumnCount() int + GetColumns() SelectExprs + } + + Withable interface { + SetWith(with *With) + } + + Distinctable interface { + MakeDistinct() + IsDistinct() bool } // SelectStatement any SELECT statement. @@ -64,19 +92,14 @@ type ( Statement InsertRows OrderAndLimit + Commented + ColumnResults + Withable + Distinctable iSelectStatement() GetLock() Lock SetLock(lock Lock) SetInto(into *SelectInto) - SetWith(with *With) - MakeDistinct() - GetColumnCount() int - GetColumns() SelectExprs - Commented - IsDistinct() bool - GetOrderBy() OrderBy - SetOrderBy(OrderBy) - GetLimit() *Limit } // DDLStatement represents any DDL Statement @@ -161,7 +184,7 @@ type ( CommonTableExpr struct { ID IdentifierCS Columns Columns - Subquery SelectStatement + Subquery TableStatement } // ChangeColumn is used to change the column definition, can also rename the column in alter table command ChangeColumn struct { @@ -303,8 +326,8 @@ type ( // Union represents a UNION statement. Union struct { With *With - Left SelectStatement - Right SelectStatement + Left TableStatement + Right TableStatement Distinct bool OrderBy OrderBy Limit *Limit @@ -543,7 +566,7 @@ type ( Definer *Definer Security string Columns Columns - Select SelectStatement + Select TableStatement CheckOption string IsReplace bool Comments *ParsedComments @@ -556,7 +579,7 @@ type ( Definer *Definer Security string Columns Columns - Select SelectStatement + Select TableStatement CheckOption string Comments *ParsedComments } @@ -727,58 +750,63 @@ type ( var _ OrderAndLimit = (*Select)(nil) var _ OrderAndLimit = (*Update)(nil) var _ OrderAndLimit = (*Delete)(nil) - -func (*Union) iStatement() {} -func (*Select) iStatement() {} -func (*Stream) iStatement() {} -func (*VStream) iStatement() {} -func (*Insert) iStatement() {} -func (*Update) iStatement() {} -func (*Delete) iStatement() {} -func (*Set) iStatement() {} -func (*DropDatabase) iStatement() {} -func (*Flush) iStatement() {} -func (*Show) iStatement() {} -func (*Use) iStatement() {} -func (*Begin) iStatement() {} -func (*Commit) iStatement() {} -func (*Rollback) iStatement() {} -func (*SRollback) iStatement() {} -func (*Savepoint) iStatement() {} -func (*Release) iStatement() {} -func (*Analyze) iStatement() {} -func (*OtherAdmin) iStatement() {} -func (*CommentOnly) iStatement() {} -func (*Select) iSelectStatement() {} -func (*Union) iSelectStatement() {} -func (*Load) iStatement() {} -func (*CreateDatabase) iStatement() {} -func (*AlterDatabase) iStatement() {} -func (*CreateTable) iStatement() {} -func (*CreateView) iStatement() {} -func (*AlterView) iStatement() {} -func (*LockTables) iStatement() {} -func (*UnlockTables) iStatement() {} -func (*AlterTable) iStatement() {} -func (*AlterVschema) iStatement() {} -func (*AlterMigration) iStatement() {} -func (*RevertMigration) iStatement() {} -func (*ShowMigrationLogs) iStatement() {} -func (*ShowThrottledApps) iStatement() {} -func (*ShowThrottlerStatus) iStatement() {} -func (*DropTable) iStatement() {} -func (*DropView) iStatement() {} -func (*TruncateTable) iStatement() {} -func (*RenameTable) iStatement() {} -func (*CallProc) iStatement() {} -func (*ExplainStmt) iStatement() {} -func (*VExplainStmt) iStatement() {} -func (*ExplainTab) iStatement() {} -func (*PrepareStmt) iStatement() {} -func (*ExecuteStmt) iStatement() {} -func (*DeallocateStmt) iStatement() {} -func (*PurgeBinaryLogs) iStatement() {} -func (*Kill) iStatement() {} +var _ OrderAndLimit = (*ValuesStatement)(nil) + +func (*Union) iStatement() {} +func (*Select) iStatement() {} +func (*ValuesStatement) iStatement() {} +func (*Stream) iStatement() {} +func (*VStream) iStatement() {} +func (*Insert) iStatement() {} +func (*Update) iStatement() {} +func (*Delete) iStatement() {} +func (*Set) iStatement() {} +func (*DropDatabase) iStatement() {} +func (*Flush) iStatement() {} +func (*Show) iStatement() {} +func (*Use) iStatement() {} +func (*Begin) iStatement() {} +func (*Commit) iStatement() {} +func (*Rollback) iStatement() {} +func (*SRollback) iStatement() {} +func (*Savepoint) iStatement() {} +func (*Release) iStatement() {} +func (*Analyze) iStatement() {} +func (*OtherAdmin) iStatement() {} +func (*CommentOnly) iStatement() {} +func (*Select) iSelectStatement() {} +func (*Select) iTableStatement() {} +func (*ValuesStatement) iSelectStatement() {} +func (*Union) iSelectStatement() {} +func (*Union) iTableStatement() {} +func (*Load) iStatement() {} +func (*CreateDatabase) iStatement() {} +func (*AlterDatabase) iStatement() {} +func (*CreateTable) iStatement() {} +func (*CreateView) iStatement() {} +func (*AlterView) iStatement() {} +func (*LockTables) iStatement() {} +func (*UnlockTables) iStatement() {} +func (*AlterTable) iStatement() {} +func (*AlterVschema) iStatement() {} +func (*AlterMigration) iStatement() {} +func (*RevertMigration) iStatement() {} +func (*ShowMigrationLogs) iStatement() {} +func (*ShowThrottledApps) iStatement() {} +func (*ShowThrottlerStatus) iStatement() {} +func (*DropTable) iStatement() {} +func (*DropView) iStatement() {} +func (*TruncateTable) iStatement() {} +func (*RenameTable) iStatement() {} +func (*CallProc) iStatement() {} +func (*ExplainStmt) iStatement() {} +func (*VExplainStmt) iStatement() {} +func (*ExplainTab) iStatement() {} +func (*PrepareStmt) iStatement() {} +func (*ExecuteStmt) iStatement() {} +func (*DeallocateStmt) iStatement() {} +func (*PurgeBinaryLogs) iStatement() {} +func (*Kill) iStatement() {} func (*CreateView) iDDLStatement() {} func (*AlterView) iDDLStatement() {} @@ -1702,9 +1730,10 @@ type InsertRows interface { SQLNode } -func (*Select) iInsertRows() {} -func (*Union) iInsertRows() {} -func (Values) iInsertRows() {} +func (*Select) iInsertRows() {} +func (*Union) iInsertRows() {} +func (Values) iInsertRows() {} +func (*ValuesStatement) iInsertRows() {} // OptLike works for create table xxx like xxx type OptLike struct { @@ -2108,13 +2137,13 @@ type ( // Subquery represents a subquery used as an value expression. Subquery struct { - Select SelectStatement + Select TableStatement } // DerivedTable represents a subquery used as a table expression. DerivedTable struct { Lateral bool - Select SelectStatement + Select TableStatement } ) @@ -3575,6 +3604,18 @@ type Limit struct { // Values represents a VALUES clause. type Values []ValTuple +// ValuesStatement represents a VALUES statement, as in VALUES ROW(1, 2), ROW(3, 4) +type ValuesStatement struct { + With *With + // One but not both of these fields can be set. + Rows Values + ListArg ListArg + + Comments *ParsedComments + Order OrderBy + Limit *Limit +} + // UpdateExprs represents a list of update expressions. type UpdateExprs []*UpdateExpr diff --git a/go/vt/sqlparser/ast_clone.go b/go/vt/sqlparser/ast_clone.go index 03a5fabe552..3c7f4fe5e6a 100644 --- a/go/vt/sqlparser/ast_clone.go +++ b/go/vt/sqlparser/ast_clone.go @@ -535,6 +535,8 @@ func CloneSQLNode(in SQLNode) SQLNode { return CloneValues(in) case *ValuesFuncExpr: return CloneRefOfValuesFuncExpr(in) + case *ValuesStatement: + return CloneRefOfValuesStatement(in) case *VarPop: return CloneRefOfVarPop(in) case *VarSamp: @@ -711,7 +713,7 @@ func CloneRefOfAlterView(n *AlterView) *AlterView { out.ViewName = CloneTableName(n.ViewName) out.Definer = CloneRefOfDefiner(n.Definer) out.Columns = CloneColumns(n.Columns) - out.Select = CloneSelectStatement(n.Select) + out.Select = CloneTableStatement(n.Select) out.Comments = CloneRefOfParsedComments(n.Comments) return &out } @@ -1023,7 +1025,7 @@ func CloneRefOfCommonTableExpr(n *CommonTableExpr) *CommonTableExpr { out := *n out.ID = CloneIdentifierCS(n.ID) out.Columns = CloneColumns(n.Columns) - out.Subquery = CloneSelectStatement(n.Subquery) + out.Subquery = CloneTableStatement(n.Subquery) return &out } @@ -1138,7 +1140,7 @@ func CloneRefOfCreateView(n *CreateView) *CreateView { out.ViewName = CloneTableName(n.ViewName) out.Definer = CloneRefOfDefiner(n.Definer) out.Columns = CloneColumns(n.Columns) - out.Select = CloneSelectStatement(n.Select) + out.Select = CloneTableStatement(n.Select) out.Comments = CloneRefOfParsedComments(n.Comments) return &out } @@ -1205,7 +1207,7 @@ func CloneRefOfDerivedTable(n *DerivedTable) *DerivedTable { return nil } out := *n - out.Select = CloneSelectStatement(n.Select) + out.Select = CloneTableStatement(n.Select) return &out } @@ -3042,7 +3044,7 @@ func CloneRefOfSubquery(n *Subquery) *Subquery { return nil } out := *n - out.Select = CloneSelectStatement(n.Select) + out.Select = CloneTableStatement(n.Select) return &out } @@ -3182,8 +3184,8 @@ func CloneRefOfUnion(n *Union) *Union { } out := *n out.With = CloneRefOfWith(n.With) - out.Left = CloneSelectStatement(n.Left) - out.Right = CloneSelectStatement(n.Right) + out.Left = CloneTableStatement(n.Left) + out.Right = CloneTableStatement(n.Right) out.OrderBy = CloneOrderBy(n.OrderBy) out.Limit = CloneRefOfLimit(n.Limit) out.Into = CloneRefOfSelectInto(n.Into) @@ -3328,6 +3330,20 @@ func CloneRefOfValuesFuncExpr(n *ValuesFuncExpr) *ValuesFuncExpr { return &out } +// CloneRefOfValuesStatement creates a deep clone of the input. +func CloneRefOfValuesStatement(n *ValuesStatement) *ValuesStatement { + if n == nil { + return nil + } + out := *n + out.With = CloneRefOfWith(n.With) + out.Rows = CloneValues(n.Rows) + out.Comments = CloneRefOfParsedComments(n.Comments) + out.Order = CloneOrderBy(n.Order) + out.Limit = CloneRefOfLimit(n.Limit) + return &out +} + // CloneRefOfVarPop creates a deep clone of the input. func CloneRefOfVarPop(n *VarPop) *VarPop { if n == nil { @@ -4107,6 +4123,8 @@ func CloneInsertRows(in InsertRows) InsertRows { return CloneRefOfUnion(in) case Values: return CloneValues(in) + case *ValuesStatement: + return CloneRefOfValuesStatement(in) default: // this should never happen return nil @@ -4287,6 +4305,8 @@ func CloneStatement(in Statement) Statement { return CloneRefOfVExplainStmt(in) case *VStream: return CloneRefOfVStream(in) + case *ValuesStatement: + return CloneRefOfValuesStatement(in) default: // this should never happen return nil @@ -4313,6 +4333,24 @@ func CloneTableExpr(in TableExpr) TableExpr { } } +// CloneTableStatement creates a deep clone of the input. +func CloneTableStatement(in TableStatement) TableStatement { + if in == nil { + return nil + } + switch in := in.(type) { + case *Select: + return CloneRefOfSelect(in) + case *Union: + return CloneRefOfUnion(in) + case *ValuesStatement: + return CloneRefOfValuesStatement(in) + default: + // this should never happen + return nil + } +} + // CloneSliceOfRefOfColumnDefinition creates a deep clone of the input. func CloneSliceOfRefOfColumnDefinition(n []*ColumnDefinition) []*ColumnDefinition { if n == nil { diff --git a/go/vt/sqlparser/ast_copy_on_rewrite.go b/go/vt/sqlparser/ast_copy_on_rewrite.go index 9b952b36dc7..f725dfc6803 100644 --- a/go/vt/sqlparser/ast_copy_on_rewrite.go +++ b/go/vt/sqlparser/ast_copy_on_rewrite.go @@ -534,6 +534,8 @@ func (c *cow) copyOnRewriteSQLNode(n SQLNode, parent SQLNode) (out SQLNode, chan return c.copyOnRewriteValues(n, parent) case *ValuesFuncExpr: return c.copyOnRewriteRefOfValuesFuncExpr(n, parent) + case *ValuesStatement: + return c.copyOnRewriteRefOfValuesStatement(n, parent) case *VarPop: return c.copyOnRewriteRefOfVarPop(n, parent) case *VarSamp: @@ -870,14 +872,14 @@ func (c *cow) copyOnRewriteRefOfAlterView(n *AlterView, parent SQLNode) (out SQL _ViewName, changedViewName := c.copyOnRewriteTableName(n.ViewName, n) _Definer, changedDefiner := c.copyOnRewriteRefOfDefiner(n.Definer, n) _Columns, changedColumns := c.copyOnRewriteColumns(n.Columns, n) - _Select, changedSelect := c.copyOnRewriteSelectStatement(n.Select, n) + _Select, changedSelect := c.copyOnRewriteTableStatement(n.Select, n) _Comments, changedComments := c.copyOnRewriteRefOfParsedComments(n.Comments, n) if changedViewName || changedDefiner || changedColumns || changedSelect || changedComments { res := *n res.ViewName, _ = _ViewName.(TableName) res.Definer, _ = _Definer.(*Definer) res.Columns, _ = _Columns.(Columns) - res.Select, _ = _Select.(SelectStatement) + res.Select, _ = _Select.(TableStatement) res.Comments, _ = _Comments.(*ParsedComments) out = &res if c.cloned != nil { @@ -1524,12 +1526,12 @@ func (c *cow) copyOnRewriteRefOfCommonTableExpr(n *CommonTableExpr, parent SQLNo if c.pre == nil || c.pre(n, parent) { _ID, changedID := c.copyOnRewriteIdentifierCS(n.ID, n) _Columns, changedColumns := c.copyOnRewriteColumns(n.Columns, n) - _Subquery, changedSubquery := c.copyOnRewriteSelectStatement(n.Subquery, n) + _Subquery, changedSubquery := c.copyOnRewriteTableStatement(n.Subquery, n) if changedID || changedColumns || changedSubquery { res := *n res.ID, _ = _ID.(IdentifierCS) res.Columns, _ = _Columns.(Columns) - res.Subquery, _ = _Subquery.(SelectStatement) + res.Subquery, _ = _Subquery.(TableStatement) out = &res if c.cloned != nil { c.cloned(n, out) @@ -1757,14 +1759,14 @@ func (c *cow) copyOnRewriteRefOfCreateView(n *CreateView, parent SQLNode) (out S _ViewName, changedViewName := c.copyOnRewriteTableName(n.ViewName, n) _Definer, changedDefiner := c.copyOnRewriteRefOfDefiner(n.Definer, n) _Columns, changedColumns := c.copyOnRewriteColumns(n.Columns, n) - _Select, changedSelect := c.copyOnRewriteSelectStatement(n.Select, n) + _Select, changedSelect := c.copyOnRewriteTableStatement(n.Select, n) _Comments, changedComments := c.copyOnRewriteRefOfParsedComments(n.Comments, n) if changedViewName || changedDefiner || changedColumns || changedSelect || changedComments { res := *n res.ViewName, _ = _ViewName.(TableName) res.Definer, _ = _Definer.(*Definer) res.Columns, _ = _Columns.(Columns) - res.Select, _ = _Select.(SelectStatement) + res.Select, _ = _Select.(TableStatement) res.Comments, _ = _Comments.(*ParsedComments) out = &res if c.cloned != nil { @@ -1898,10 +1900,10 @@ func (c *cow) copyOnRewriteRefOfDerivedTable(n *DerivedTable, parent SQLNode) (o } out = n if c.pre == nil || c.pre(n, parent) { - _Select, changedSelect := c.copyOnRewriteSelectStatement(n.Select, n) + _Select, changedSelect := c.copyOnRewriteTableStatement(n.Select, n) if changedSelect { res := *n - res.Select, _ = _Select.(SelectStatement) + res.Select, _ = _Select.(TableStatement) out = &res if c.cloned != nil { c.cloned(n, out) @@ -5790,10 +5792,10 @@ func (c *cow) copyOnRewriteRefOfSubquery(n *Subquery, parent SQLNode) (out SQLNo } out = n if c.pre == nil || c.pre(n, parent) { - _Select, changedSelect := c.copyOnRewriteSelectStatement(n.Select, n) + _Select, changedSelect := c.copyOnRewriteTableStatement(n.Select, n) if changedSelect { res := *n - res.Select, _ = _Select.(SelectStatement) + res.Select, _ = _Select.(TableStatement) out = &res if c.cloned != nil { c.cloned(n, out) @@ -6101,16 +6103,16 @@ func (c *cow) copyOnRewriteRefOfUnion(n *Union, parent SQLNode) (out SQLNode, ch out = n if c.pre == nil || c.pre(n, parent) { _With, changedWith := c.copyOnRewriteRefOfWith(n.With, n) - _Left, changedLeft := c.copyOnRewriteSelectStatement(n.Left, n) - _Right, changedRight := c.copyOnRewriteSelectStatement(n.Right, n) + _Left, changedLeft := c.copyOnRewriteTableStatement(n.Left, n) + _Right, changedRight := c.copyOnRewriteTableStatement(n.Right, n) _OrderBy, changedOrderBy := c.copyOnRewriteOrderBy(n.OrderBy, n) _Limit, changedLimit := c.copyOnRewriteRefOfLimit(n.Limit, n) _Into, changedInto := c.copyOnRewriteRefOfSelectInto(n.Into, n) if changedWith || changedLeft || changedRight || changedOrderBy || changedLimit || changedInto { res := *n res.With, _ = _With.(*With) - res.Left, _ = _Left.(SelectStatement) - res.Right, _ = _Right.(SelectStatement) + res.Left, _ = _Left.(TableStatement) + res.Right, _ = _Right.(TableStatement) res.OrderBy, _ = _OrderBy.(OrderBy) res.Limit, _ = _Limit.(*Limit) res.Into, _ = _Into.(*SelectInto) @@ -6409,6 +6411,38 @@ func (c *cow) copyOnRewriteRefOfValuesFuncExpr(n *ValuesFuncExpr, parent SQLNode } return } +func (c *cow) copyOnRewriteRefOfValuesStatement(n *ValuesStatement, parent SQLNode) (out SQLNode, changed bool) { + if n == nil || c.cursor.stop { + return n, false + } + out = n + if c.pre == nil || c.pre(n, parent) { + _With, changedWith := c.copyOnRewriteRefOfWith(n.With, n) + _Rows, changedRows := c.copyOnRewriteValues(n.Rows, n) + _ListArg, changedListArg := c.copyOnRewriteListArg(n.ListArg, n) + _Comments, changedComments := c.copyOnRewriteRefOfParsedComments(n.Comments, n) + _Order, changedOrder := c.copyOnRewriteOrderBy(n.Order, n) + _Limit, changedLimit := c.copyOnRewriteRefOfLimit(n.Limit, n) + if changedWith || changedRows || changedListArg || changedComments || changedOrder || changedLimit { + res := *n + res.With, _ = _With.(*With) + res.Rows, _ = _Rows.(Values) + res.ListArg, _ = _ListArg.(ListArg) + res.Comments, _ = _Comments.(*ParsedComments) + res.Order, _ = _Order.(OrderBy) + res.Limit, _ = _Limit.(*Limit) + out = &res + if c.cloned != nil { + c.cloned(n, out) + } + changed = true + } + } + if c.post != nil { + out, changed = c.postVisit(out, parent, changed) + } + return +} func (c *cow) copyOnRewriteRefOfVarPop(n *VarPop, parent SQLNode) (out SQLNode, changed bool) { if n == nil || c.cursor.stop { return n, false @@ -7366,6 +7400,8 @@ func (c *cow) copyOnRewriteInsertRows(n InsertRows, parent SQLNode) (out SQLNode return c.copyOnRewriteRefOfUnion(n, parent) case Values: return c.copyOnRewriteValues(n, parent) + case *ValuesStatement: + return c.copyOnRewriteRefOfValuesStatement(n, parent) default: // this should never happen return nil, false @@ -7536,6 +7572,8 @@ func (c *cow) copyOnRewriteStatement(n Statement, parent SQLNode) (out SQLNode, return c.copyOnRewriteRefOfVExplainStmt(n, parent) case *VStream: return c.copyOnRewriteRefOfVStream(n, parent) + case *ValuesStatement: + return c.copyOnRewriteRefOfValuesStatement(n, parent) default: // this should never happen return nil, false @@ -7559,6 +7597,22 @@ func (c *cow) copyOnRewriteTableExpr(n TableExpr, parent SQLNode) (out SQLNode, return nil, false } } +func (c *cow) copyOnRewriteTableStatement(n TableStatement, parent SQLNode) (out SQLNode, changed bool) { + if n == nil || c.cursor.stop { + return n, false + } + switch n := n.(type) { + case *Select: + return c.copyOnRewriteRefOfSelect(n, parent) + case *Union: + return c.copyOnRewriteRefOfUnion(n, parent) + case *ValuesStatement: + return c.copyOnRewriteRefOfValuesStatement(n, parent) + default: + // this should never happen + return nil, false + } +} func (c *cow) copyOnRewriteAlgorithmValue(n AlgorithmValue, parent SQLNode) (out SQLNode, changed bool) { if c.cursor.stop { return n, false diff --git a/go/vt/sqlparser/ast_equals.go b/go/vt/sqlparser/ast_equals.go index c4c0b34c271..93f10376177 100644 --- a/go/vt/sqlparser/ast_equals.go +++ b/go/vt/sqlparser/ast_equals.go @@ -1562,6 +1562,12 @@ func (cmp *Comparator) SQLNode(inA, inB SQLNode) bool { return false } return cmp.RefOfValuesFuncExpr(a, b) + case *ValuesStatement: + b, ok := inB.(*ValuesStatement) + if !ok { + return false + } + return cmp.RefOfValuesStatement(a, b) case *VarPop: b, ok := inB.(*VarPop) if !ok { @@ -1826,7 +1832,7 @@ func (cmp *Comparator) RefOfAlterView(a, b *AlterView) bool { cmp.TableName(a.ViewName, b.ViewName) && cmp.RefOfDefiner(a.Definer, b.Definer) && cmp.Columns(a.Columns, b.Columns) && - cmp.SelectStatement(a.Select, b.Select) && + cmp.TableStatement(a.Select, b.Select) && cmp.RefOfParsedComments(a.Comments, b.Comments) } @@ -2195,7 +2201,7 @@ func (cmp *Comparator) RefOfCommonTableExpr(a, b *CommonTableExpr) bool { } return cmp.IdentifierCS(a.ID, b.ID) && cmp.Columns(a.Columns, b.Columns) && - cmp.SelectStatement(a.Subquery, b.Subquery) + cmp.TableStatement(a.Subquery, b.Subquery) } // RefOfComparisonExpr does deep equals between the two objects. @@ -2334,7 +2340,7 @@ func (cmp *Comparator) RefOfCreateView(a, b *CreateView) bool { cmp.TableName(a.ViewName, b.ViewName) && cmp.RefOfDefiner(a.Definer, b.Definer) && cmp.Columns(a.Columns, b.Columns) && - cmp.SelectStatement(a.Select, b.Select) && + cmp.TableStatement(a.Select, b.Select) && cmp.RefOfParsedComments(a.Comments, b.Comments) } @@ -2413,7 +2419,7 @@ func (cmp *Comparator) RefOfDerivedTable(a, b *DerivedTable) bool { return false } return a.Lateral == b.Lateral && - cmp.SelectStatement(a.Select, b.Select) + cmp.TableStatement(a.Select, b.Select) } // RefOfDropColumn does deep equals between the two objects. @@ -4525,7 +4531,7 @@ func (cmp *Comparator) RefOfSubquery(a, b *Subquery) bool { if a == nil || b == nil { return false } - return cmp.SelectStatement(a.Select, b.Select) + return cmp.TableStatement(a.Select, b.Select) } // RefOfSubstrExpr does deep equals between the two objects. @@ -4685,8 +4691,8 @@ func (cmp *Comparator) RefOfUnion(a, b *Union) bool { } return a.Distinct == b.Distinct && cmp.RefOfWith(a.With, b.With) && - cmp.SelectStatement(a.Left, b.Left) && - cmp.SelectStatement(a.Right, b.Right) && + cmp.TableStatement(a.Left, b.Left) && + cmp.TableStatement(a.Right, b.Right) && cmp.OrderBy(a.OrderBy, b.OrderBy) && cmp.RefOfLimit(a.Limit, b.Limit) && a.Lock == b.Lock && @@ -4847,6 +4853,22 @@ func (cmp *Comparator) RefOfValuesFuncExpr(a, b *ValuesFuncExpr) bool { return cmp.RefOfColName(a.Name, b.Name) } +// RefOfValuesStatement does deep equals between the two objects. +func (cmp *Comparator) RefOfValuesStatement(a, b *ValuesStatement) bool { + if a == b { + return true + } + if a == nil || b == nil { + return false + } + return cmp.RefOfWith(a.With, b.With) && + cmp.Values(a.Rows, b.Rows) && + a.ListArg == b.ListArg && + cmp.RefOfParsedComments(a.Comments, b.Comments) && + cmp.OrderBy(a.Order, b.Order) && + cmp.RefOfLimit(a.Limit, b.Limit) +} + // RefOfVarPop does deep equals between the two objects. func (cmp *Comparator) RefOfVarPop(a, b *VarPop) bool { if a == b { @@ -6705,6 +6727,12 @@ func (cmp *Comparator) InsertRows(inA, inB InsertRows) bool { return false } return cmp.Values(a, b) + case *ValuesStatement: + b, ok := inB.(*ValuesStatement) + if !ok { + return false + } + return cmp.RefOfValuesStatement(a, b) default: // this should never happen return false @@ -7140,6 +7168,12 @@ func (cmp *Comparator) Statement(inA, inB Statement) bool { return false } return cmp.RefOfVStream(a, b) + case *ValuesStatement: + b, ok := inB.(*ValuesStatement) + if !ok { + return false + } + return cmp.RefOfValuesStatement(a, b) default: // this should never happen return false @@ -7185,6 +7219,39 @@ func (cmp *Comparator) TableExpr(inA, inB TableExpr) bool { } } +// TableStatement does deep equals between the two objects. +func (cmp *Comparator) TableStatement(inA, inB TableStatement) bool { + if inA == nil && inB == nil { + return true + } + if inA == nil || inB == nil { + return false + } + switch a := inA.(type) { + case *Select: + b, ok := inB.(*Select) + if !ok { + return false + } + return cmp.RefOfSelect(a, b) + case *Union: + b, ok := inB.(*Union) + if !ok { + return false + } + return cmp.RefOfUnion(a, b) + case *ValuesStatement: + b, ok := inB.(*ValuesStatement) + if !ok { + return false + } + return cmp.RefOfValuesStatement(a, b) + default: + // this should never happen + return false + } +} + // SliceOfRefOfColumnDefinition does deep equals between the two objects. func (cmp *Comparator) SliceOfRefOfColumnDefinition(a, b []*ColumnDefinition) bool { if len(a) != len(b) { diff --git a/go/vt/sqlparser/ast_format.go b/go/vt/sqlparser/ast_format.go index dff17911d8e..37539c450b2 100644 --- a/go/vt/sqlparser/ast_format.go +++ b/go/vt/sqlparser/ast_format.go @@ -120,6 +120,26 @@ func (node *VStream) Format(buf *TrackedBuffer) { node.Comments, node.SelectExpr, node.Table) } +// Format formats the node. +func (node *ValuesStatement) Format(buf *TrackedBuffer) { + if node.With != nil { + buf.astPrintf(node, "%v", node.With) + } + buf.astPrintf(node, "values %v", node.Comments) + if node.ListArg != "" { + buf.astPrintf(node, "%v", node.ListArg) + } else { + for i, row := range node.Rows { + buf.astPrintf(node, "row%v", row) + if i < len(node.Rows)-1 { + buf.WriteString(", ") + } + } + } + buf.astPrintf(node, "%v%v", + node.Order, node.Limit) +} + // Format formats the node. func (node *Stream) Format(buf *TrackedBuffer) { buf.astPrintf(node, "stream %v%v from %v", diff --git a/go/vt/sqlparser/ast_format_fast.go b/go/vt/sqlparser/ast_format_fast.go index 9855c70a21d..7a818faf0c0 100644 --- a/go/vt/sqlparser/ast_format_fast.go +++ b/go/vt/sqlparser/ast_format_fast.go @@ -141,6 +141,30 @@ func (node *VStream) FormatFast(buf *TrackedBuffer) { } +// FormatFast formats the node. +func (node *ValuesStatement) FormatFast(buf *TrackedBuffer) { + if node.With != nil { + node.With.FormatFast(buf) + } + buf.WriteString("values ") + node.Comments.FormatFast(buf) + if node.ListArg != "" { + node.ListArg.FormatFast(buf) + } else { + for i, row := range node.Rows { + buf.WriteString("row") + row.FormatFast(buf) + if i < len(node.Rows)-1 { + buf.WriteString(", ") + } + } + } + + node.Order.FormatFast(buf) + node.Limit.FormatFast(buf) + +} + // FormatFast formats the node. func (node *Stream) FormatFast(buf *TrackedBuffer) { buf.WriteString("stream ") diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index 836c824010d..e28c17a4745 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -640,6 +640,26 @@ func parseBindVariable(yylex yyLexer, bvar string) *Argument { return NewArgument(bvar) } +func setIntoIfPossible(lexer yyLexer, tblSubquery TableStatement, into *SelectInto) { + selStmt, ok := tblSubquery.(SelectStatement) + if !ok { + lexer.Error("VALUES does not support INTO") + return + } + + selStmt.SetInto(into) +} + +func setLockIfPossible(lexer yyLexer, tblSubquery TableStatement, lock Lock) { + selStmt, ok := tblSubquery.(SelectStatement) + if !ok { + lexer.Error("VALUES does not support LOCK") + return + } + + selStmt.SetLock(lock) +} + func NewTypedArgument(in string, t sqltypes.Type) *Argument { return &Argument{Name: in, Type: t} } @@ -755,12 +775,12 @@ func NewTableNameWithQualifier(name, qualifier string) TableName { } // NewSubquery makes a new Subquery -func NewSubquery(selectStatement SelectStatement) *Subquery { +func NewSubquery(selectStatement TableStatement) *Subquery { return &Subquery{Select: selectStatement} } // NewDerivedTable makes a new DerivedTable -func NewDerivedTable(lateral bool, selectStatement SelectStatement) *DerivedTable { +func NewDerivedTable(lateral bool, selectStatement TableStatement) *DerivedTable { return &DerivedTable{ Lateral: lateral, Select: selectStatement, @@ -1391,7 +1411,7 @@ func (node *Union) GetParsedComments() *ParsedComments { return node.Left.GetParsedComments() } -func requiresParen(stmt SelectStatement) bool { +func requiresParen(stmt TableStatement) bool { switch node := stmt.(type) { case *Union: return len(node.OrderBy) != 0 || node.Lock != 0 || node.Into != nil || node.Limit != nil @@ -1402,10 +1422,6 @@ func requiresParen(stmt SelectStatement) bool { return false } -func setLockInSelect(stmt SelectStatement, lock Lock) { - stmt.SetLock(lock) -} - // ToString returns the string associated with the DDLAction Enum func (action DDLAction) ToString() string { switch action { @@ -2345,26 +2361,30 @@ func setFuncArgs(aggr AggrFunc, exprs Exprs, name string) error { } // GetFirstSelect gets the first select statement -func GetFirstSelect(selStmt SelectStatement) *Select { +func GetFirstSelect(selStmt TableStatement) (*Select, error) { if selStmt == nil { - return nil + return nil, nil } switch node := selStmt.(type) { case *Select: - return node + return node, nil + case *ValuesStatement: + return nil, vterrors.VT12001("first table_reference as VALUES") case *Union: return GetFirstSelect(node.Left) } - panic("[BUG]: unknown type for SelectStatement") + return nil, vterrors.VT13001(fmt.Sprintf("unknown type for SelectStatement: %T", selStmt)) } // GetAllSelects gets all the select statement s -func GetAllSelects(selStmt SelectStatement) []*Select { +func GetAllSelects(selStmt TableStatement) []TableStatement { switch node := selStmt.(type) { case *Select: - return []*Select{node} + return []TableStatement{node} case *Union: return append(GetAllSelects(node.Left), GetAllSelects(node.Right)...) + case *ValuesStatement: + return []TableStatement{node} } panic("[BUG]: unknown type for SelectStatement") } @@ -2409,29 +2429,38 @@ func RemoveKeyspaceInCol(in SQLNode) { }, in) } -// RemoveKeyspaceInTables removes the Qualifier on all TableNames in the AST -func RemoveKeyspaceInTables(in SQLNode) { - // Walk will only return an error if we return an error from the inner func. safe to ignore here - Rewrite(in, nil, func(cursor *Cursor) bool { - if tbl, ok := cursor.Node().(TableName); ok && tbl.Qualifier.NotEmpty() { - tbl.Qualifier = NewIdentifierCS("") - cursor.Replace(tbl) - } +// RemoveKeyspace removes the keyspace qualifier from all ColName and TableName +func RemoveKeyspace(in SQLNode) { + removeKeyspace(in, func(_ string) bool { + return true // Always remove + }) +} - return true +// RemoveSpecificKeyspace removes the keyspace qualifier from all ColName and TableName +// when it matches the keyspace provided +func RemoveSpecificKeyspace(in SQLNode, keyspace string) { + removeKeyspace(in, func(qualifier string) bool { + return qualifier == keyspace // Remove only if it matches the provided keyspace }) } -// RemoveKeyspace removes the Qualifier.Qualifier on all ColNames and Qualifier on all TableNames in the AST -func RemoveKeyspace(in SQLNode) { +// RemoveKeyspaceIgnoreSysSchema removes the keyspace qualifier from all ColName and TableName +// except for the system schema qualifier. +func RemoveKeyspaceIgnoreSysSchema(in SQLNode) { + removeKeyspace(in, func(qualifier string) bool { + return qualifier != "" && !SystemSchema(qualifier) // Remove if it's not empty and not a system schema + }) +} + +func removeKeyspace(in SQLNode, shouldRemove func(qualifier string) bool) { Rewrite(in, nil, func(cursor *Cursor) bool { switch expr := cursor.Node().(type) { case *ColName: - if expr.Qualifier.Qualifier.NotEmpty() { + if shouldRemove(expr.Qualifier.Qualifier.String()) { expr.Qualifier.Qualifier = NewIdentifierCS("") } case TableName: - if expr.Qualifier.NotEmpty() { + if shouldRemove(expr.Qualifier.String()) { expr.Qualifier = NewIdentifierCS("") cursor.Replace(expr) } @@ -2753,7 +2782,7 @@ func MakeColumns(colNames ...string) Columns { return cols } -func VisitAllSelects(in SelectStatement, f func(p *Select, idx int) error) error { +func VisitAllSelects(in TableStatement, f func(p *Select, idx int) error) error { v := visitor{} return v.visitAllSelects(in, f) } @@ -2762,7 +2791,7 @@ type visitor struct { idx int } -func (v *visitor) visitAllSelects(in SelectStatement, f func(p *Select, idx int) error) error { +func (v *visitor) visitAllSelects(in TableStatement, f func(p *Select, idx int) error) error { switch sel := in.(type) { case *Select: err := f(sel, v.idx) @@ -2856,6 +2885,30 @@ func (node *Update) SetLimit(limit *Limit) { node.Limit = limit } +func (node *Update) GetOrderBy() OrderBy { + return node.OrderBy +} + +func (node *Update) SetOrderBy(by OrderBy) { + node.OrderBy = by +} + +func (node *Update) GetLimit() *Limit { + return node.Limit +} + +func (node *Delete) GetOrderBy() OrderBy { + return node.OrderBy +} + +func (node *Delete) SetOrderBy(by OrderBy) { + node.OrderBy = by +} + +func (node *Delete) GetLimit() *Limit { + return node.Limit +} + func (node *Delete) AddOrder(order *Order) { node.OrderBy = append(node.OrderBy, order) } @@ -2962,3 +3015,50 @@ func ExtractAllTables(stmt Statement) []string { }, stmt) return tables } + +var _ TableStatement = (*ValuesStatement)(nil) + +func (node *ValuesStatement) iTableStatement() {} + +func (node *ValuesStatement) SetWith(with *With) { + node.With = with +} + +func (node *ValuesStatement) GetOrderBy() OrderBy { + return node.Order +} + +func (node *ValuesStatement) SetOrderBy(by OrderBy) { + node.Order = by +} + +func (node *ValuesStatement) GetLimit() *Limit { + return node.Limit +} + +func (node *ValuesStatement) AddOrder(order *Order) { + node.Order = append(node.Order, order) +} + +func (node *ValuesStatement) SetLimit(limit *Limit) { + node.Limit = limit +} + +func (node *ValuesStatement) GetColumnCount() int { + if len(node.Rows) > 0 { + return len(node.Rows[0]) + } + panic("no columns available") // TODO: we need a better solution than a panic +} + +func (node *ValuesStatement) GetColumns() (result SelectExprs) { + columnCount := node.GetColumnCount() + for i := range columnCount { + result = append(result, &AliasedExpr{Expr: NewColName(fmt.Sprintf("column_%d", i))}) + } + panic("no columns available") // TODO: we need a better solution than a panic +} + +func (node *ValuesStatement) SetComments(comments Comments) {} + +func (node *ValuesStatement) GetParsedComments() *ParsedComments { return nil } diff --git a/go/vt/sqlparser/ast_funcs_test.go b/go/vt/sqlparser/ast_funcs_test.go index a3b744729f4..009f3e6cc15 100644 --- a/go/vt/sqlparser/ast_funcs_test.go +++ b/go/vt/sqlparser/ast_funcs_test.go @@ -219,3 +219,28 @@ func TestExtractTables(t *testing.T) { }) } } + +// TestRemoveKeyspace tests the RemoveKeyspaceIgnoreSysSchema function. +// It removes all the keyspace except system schema. +func TestRemoveKeyspaceIgnoreSysSchema(t *testing.T) { + stmt, err := NewTestParser().Parse("select 1 from uks.unsharded join information_schema.tables") + require.NoError(t, err) + RemoveKeyspaceIgnoreSysSchema(stmt) + + require.Equal(t, "select 1 from unsharded join information_schema.`tables`", String(stmt)) +} + +// TestRemoveSpecificKeyspace tests the RemoveSpecificKeyspace function. +// It removes the specific keyspace from the database qualifier. +func TestRemoveSpecificKeyspace(t *testing.T) { + stmt, err := NewTestParser().Parse("select 1 from uks.unsharded") + require.NoError(t, err) + + // does not match + RemoveSpecificKeyspace(stmt, "ks2") + require.Equal(t, "select 1 from uks.unsharded", String(stmt)) + + // match + RemoveSpecificKeyspace(stmt, "uks") + require.Equal(t, "select 1 from unsharded", String(stmt)) +} diff --git a/go/vt/sqlparser/ast_rewrite.go b/go/vt/sqlparser/ast_rewrite.go index e65b243d7e1..690b381b082 100644 --- a/go/vt/sqlparser/ast_rewrite.go +++ b/go/vt/sqlparser/ast_rewrite.go @@ -534,6 +534,8 @@ func (a *application) rewriteSQLNode(parent SQLNode, node SQLNode, replacer repl return a.rewriteValues(parent, node, replacer) case *ValuesFuncExpr: return a.rewriteRefOfValuesFuncExpr(parent, node, replacer) + case *ValuesStatement: + return a.rewriteRefOfValuesStatement(parent, node, replacer) case *VarPop: return a.rewriteRefOfVarPop(parent, node, replacer) case *VarSamp: @@ -983,8 +985,8 @@ func (a *application) rewriteRefOfAlterView(parent SQLNode, node *AlterView, rep }) { return false } - if !a.rewriteSelectStatement(node, node.Select, func(newNode, parent SQLNode) { - parent.(*AlterView).Select = newNode.(SelectStatement) + if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { + parent.(*AlterView).Select = newNode.(TableStatement) }) { return false } @@ -1969,8 +1971,8 @@ func (a *application) rewriteRefOfCommonTableExpr(parent SQLNode, node *CommonTa }) { return false } - if !a.rewriteSelectStatement(node, node.Subquery, func(newNode, parent SQLNode) { - parent.(*CommonTableExpr).Subquery = newNode.(SelectStatement) + if !a.rewriteTableStatement(node, node.Subquery, func(newNode, parent SQLNode) { + parent.(*CommonTableExpr).Subquery = newNode.(TableStatement) }) { return false } @@ -2321,8 +2323,8 @@ func (a *application) rewriteRefOfCreateView(parent SQLNode, node *CreateView, r }) { return false } - if !a.rewriteSelectStatement(node, node.Select, func(newNode, parent SQLNode) { - parent.(*CreateView).Select = newNode.(SelectStatement) + if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { + parent.(*CreateView).Select = newNode.(TableStatement) }) { return false } @@ -2536,8 +2538,8 @@ func (a *application) rewriteRefOfDerivedTable(parent SQLNode, node *DerivedTabl return true } } - if !a.rewriteSelectStatement(node, node.Select, func(newNode, parent SQLNode) { - parent.(*DerivedTable).Select = newNode.(SelectStatement) + if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { + parent.(*DerivedTable).Select = newNode.(TableStatement) }) { return false } @@ -8337,8 +8339,8 @@ func (a *application) rewriteRefOfSubquery(parent SQLNode, node *Subquery, repla return true } } - if !a.rewriteSelectStatement(node, node.Select, func(newNode, parent SQLNode) { - parent.(*Subquery).Select = newNode.(SelectStatement) + if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { + parent.(*Subquery).Select = newNode.(TableStatement) }) { return false } @@ -8797,13 +8799,13 @@ func (a *application) rewriteRefOfUnion(parent SQLNode, node *Union, replacer re }) { return false } - if !a.rewriteSelectStatement(node, node.Left, func(newNode, parent SQLNode) { - parent.(*Union).Left = newNode.(SelectStatement) + if !a.rewriteTableStatement(node, node.Left, func(newNode, parent SQLNode) { + parent.(*Union).Left = newNode.(TableStatement) }) { return false } - if !a.rewriteSelectStatement(node, node.Right, func(newNode, parent SQLNode) { - parent.(*Union).Right = newNode.(SelectStatement) + if !a.rewriteTableStatement(node, node.Right, func(newNode, parent SQLNode) { + parent.(*Union).Right = newNode.(TableStatement) }) { return false } @@ -9264,6 +9266,58 @@ func (a *application) rewriteRefOfValuesFuncExpr(parent SQLNode, node *ValuesFun } return true } +func (a *application) rewriteRefOfValuesStatement(parent SQLNode, node *ValuesStatement, replacer replacerFunc) bool { + if node == nil { + return true + } + if a.pre != nil { + a.cur.replacer = replacer + a.cur.parent = parent + a.cur.node = node + if !a.pre(&a.cur) { + return true + } + } + if !a.rewriteRefOfWith(node, node.With, func(newNode, parent SQLNode) { + parent.(*ValuesStatement).With = newNode.(*With) + }) { + return false + } + if !a.rewriteValues(node, node.Rows, func(newNode, parent SQLNode) { + parent.(*ValuesStatement).Rows = newNode.(Values) + }) { + return false + } + if !a.rewriteListArg(node, node.ListArg, func(newNode, parent SQLNode) { + parent.(*ValuesStatement).ListArg = newNode.(ListArg) + }) { + return false + } + if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { + parent.(*ValuesStatement).Comments = newNode.(*ParsedComments) + }) { + return false + } + if !a.rewriteOrderBy(node, node.Order, func(newNode, parent SQLNode) { + parent.(*ValuesStatement).Order = newNode.(OrderBy) + }) { + return false + } + if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { + parent.(*ValuesStatement).Limit = newNode.(*Limit) + }) { + return false + } + if a.post != nil { + a.cur.replacer = replacer + a.cur.parent = parent + a.cur.node = node + if !a.post(&a.cur) { + return false + } + } + return true +} func (a *application) rewriteRefOfVarPop(parent SQLNode, node *VarPop, replacer replacerFunc) bool { if node == nil { return true @@ -10358,6 +10412,8 @@ func (a *application) rewriteInsertRows(parent SQLNode, node InsertRows, replace return a.rewriteRefOfUnion(parent, node, replacer) case Values: return a.rewriteValues(parent, node, replacer) + case *ValuesStatement: + return a.rewriteRefOfValuesStatement(parent, node, replacer) default: // this should never happen return true @@ -10528,6 +10584,8 @@ func (a *application) rewriteStatement(parent SQLNode, node Statement, replacer return a.rewriteRefOfVExplainStmt(parent, node, replacer) case *VStream: return a.rewriteRefOfVStream(parent, node, replacer) + case *ValuesStatement: + return a.rewriteRefOfValuesStatement(parent, node, replacer) default: // this should never happen return true @@ -10551,6 +10609,22 @@ func (a *application) rewriteTableExpr(parent SQLNode, node TableExpr, replacer return true } } +func (a *application) rewriteTableStatement(parent SQLNode, node TableStatement, replacer replacerFunc) bool { + if node == nil { + return true + } + switch node := node.(type) { + case *Select: + return a.rewriteRefOfSelect(parent, node, replacer) + case *Union: + return a.rewriteRefOfUnion(parent, node, replacer) + case *ValuesStatement: + return a.rewriteRefOfValuesStatement(parent, node, replacer) + default: + // this should never happen + return true + } +} func (a *application) rewriteAlgorithmValue(parent SQLNode, node AlgorithmValue, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer diff --git a/go/vt/sqlparser/ast_rewriting.go b/go/vt/sqlparser/ast_rewriting.go index ef46b124875..05e7e290fc1 100644 --- a/go/vt/sqlparser/ast_rewriting.go +++ b/go/vt/sqlparser/ast_rewriting.go @@ -38,7 +38,7 @@ type RewriteASTResult struct { } type VSchemaViews interface { - FindView(name TableName) SelectStatement + FindView(name TableName) TableStatement } // PrepareAST will normalize the query @@ -257,7 +257,7 @@ func (er *astRewriter) rewriteAliasedTable(cursor *Cursor, node *AliasedTableExp } // Aha! It's a view. Let's replace it with a derived table - node.Expr = &DerivedTable{Select: CloneSelectStatement(view)} + node.Expr = &DerivedTable{Select: Clone(view)} // TODO: this is a bit hacky. We want to update the schema def so it contains new types if node.As.IsEmpty() { node.As = NewIdentifierCS(tblName) } diff --git a/go/vt/sqlparser/ast_rewriting_test.go b/go/vt/sqlparser/ast_rewriting_test.go index 3ad9a5298c4..8b3e3d44c54 100644 --- a/go/vt/sqlparser/ast_rewriting_test.go +++ b/go/vt/sqlparser/ast_rewriting_test.go @@ -388,7 +388,7 @@ func TestRewrites(in *testing.T) { type fakeViews struct{} -func (*fakeViews) FindView(name TableName) SelectStatement { +func (*fakeViews) FindView(name TableName) TableStatement { if name.Name.String() != "user_details" { return nil } @@ -397,7 +397,7 @@ func (*fakeViews) FindView(name TableName) SelectStatement { if err != nil { return nil } - return statement.(SelectStatement) + return statement.(TableStatement) } func TestRewritesWithSetVarComment(in *testing.T) { diff --git a/go/vt/sqlparser/ast_visit.go b/go/vt/sqlparser/ast_visit.go index 439d0bffeec..a7fbbe02118 100644 --- a/go/vt/sqlparser/ast_visit.go +++ b/go/vt/sqlparser/ast_visit.go @@ -534,6 +534,8 @@ func VisitSQLNode(in SQLNode, f Visit) error { return VisitValues(in, f) case *ValuesFuncExpr: return VisitRefOfValuesFuncExpr(in, f) + case *ValuesStatement: + return VisitRefOfValuesStatement(in, f) case *VarPop: return VisitRefOfVarPop(in, f) case *VarSamp: @@ -764,7 +766,7 @@ func VisitRefOfAlterView(in *AlterView, f Visit) error { if err := VisitColumns(in.Columns, f); err != nil { return err } - if err := VisitSelectStatement(in.Select, f); err != nil { + if err := VisitTableStatement(in.Select, f); err != nil { return err } if err := VisitRefOfParsedComments(in.Comments, f); err != nil { @@ -1175,7 +1177,7 @@ func VisitRefOfCommonTableExpr(in *CommonTableExpr, f Visit) error { if err := VisitColumns(in.Columns, f); err != nil { return err } - if err := VisitSelectStatement(in.Subquery, f); err != nil { + if err := VisitTableStatement(in.Subquery, f); err != nil { return err } return nil @@ -1328,7 +1330,7 @@ func VisitRefOfCreateView(in *CreateView, f Visit) error { if err := VisitColumns(in.Columns, f); err != nil { return err } - if err := VisitSelectStatement(in.Select, f); err != nil { + if err := VisitTableStatement(in.Select, f); err != nil { return err } if err := VisitRefOfParsedComments(in.Comments, f); err != nil { @@ -1423,7 +1425,7 @@ func VisitRefOfDerivedTable(in *DerivedTable, f Visit) error { if cont, err := f(in); err != nil || !cont { return err } - if err := VisitSelectStatement(in.Select, f); err != nil { + if err := VisitTableStatement(in.Select, f); err != nil { return err } return nil @@ -3890,7 +3892,7 @@ func VisitRefOfSubquery(in *Subquery, f Visit) error { if cont, err := f(in); err != nil || !cont { return err } - if err := VisitSelectStatement(in.Select, f); err != nil { + if err := VisitTableStatement(in.Select, f); err != nil { return err } return nil @@ -4075,10 +4077,10 @@ func VisitRefOfUnion(in *Union, f Visit) error { if err := VisitRefOfWith(in.With, f); err != nil { return err } - if err := VisitSelectStatement(in.Left, f); err != nil { + if err := VisitTableStatement(in.Left, f); err != nil { return err } - if err := VisitSelectStatement(in.Right, f); err != nil { + if err := VisitTableStatement(in.Right, f); err != nil { return err } if err := VisitOrderBy(in.OrderBy, f); err != nil { @@ -4280,6 +4282,33 @@ func VisitRefOfValuesFuncExpr(in *ValuesFuncExpr, f Visit) error { } return nil } +func VisitRefOfValuesStatement(in *ValuesStatement, f Visit) error { + if in == nil { + return nil + } + if cont, err := f(in); err != nil || !cont { + return err + } + if err := VisitRefOfWith(in.With, f); err != nil { + return err + } + if err := VisitValues(in.Rows, f); err != nil { + return err + } + if err := VisitListArg(in.ListArg, f); err != nil { + return err + } + if err := VisitRefOfParsedComments(in.Comments, f); err != nil { + return err + } + if err := VisitOrderBy(in.Order, f); err != nil { + return err + } + if err := VisitRefOfLimit(in.Limit, f); err != nil { + return err + } + return nil +} func VisitRefOfVarPop(in *VarPop, f Visit) error { if in == nil { return nil @@ -5098,6 +5127,8 @@ func VisitInsertRows(in InsertRows, f Visit) error { return VisitRefOfUnion(in, f) case Values: return VisitValues(in, f) + case *ValuesStatement: + return VisitRefOfValuesStatement(in, f) default: // this should never happen return nil @@ -5268,6 +5299,8 @@ func VisitStatement(in Statement, f Visit) error { return VisitRefOfVExplainStmt(in, f) case *VStream: return VisitRefOfVStream(in, f) + case *ValuesStatement: + return VisitRefOfValuesStatement(in, f) default: // this should never happen return nil @@ -5291,6 +5324,22 @@ func VisitTableExpr(in TableExpr, f Visit) error { return nil } } +func VisitTableStatement(in TableStatement, f Visit) error { + if in == nil { + return nil + } + switch in := in.(type) { + case *Select: + return VisitRefOfSelect(in, f) + case *Union: + return VisitRefOfUnion(in, f) + case *ValuesStatement: + return VisitRefOfValuesStatement(in, f) + default: + // this should never happen + return nil + } +} func VisitAlgorithmValue(in AlgorithmValue, f Visit) error { _, err := f(in) return err diff --git a/go/vt/sqlparser/cached_size.go b/go/vt/sqlparser/cached_size.go index 524291a03b4..7183ff18e28 100644 --- a/go/vt/sqlparser/cached_size.go +++ b/go/vt/sqlparser/cached_size.go @@ -272,7 +272,7 @@ func (cached *AlterView) CachedSize(alloc bool) int64 { size += elem.CachedSize(false) } } - // field Select vitess.io/vitess/go/vt/sqlparser.SelectStatement + // field Select vitess.io/vitess/go/vt/sqlparser.TableStatement if cc, ok := cached.Select.(cachedObject); ok { size += cc.CachedSize(true) } @@ -788,6 +788,20 @@ func (cached *ColumnTypeOptions) CachedSize(alloc bool) int64 { size += cached.SRID.CachedSize(true) return size } +func (cached *Columns) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(32)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} //go:nocheckptr func (cached *CommentDirectives) CachedSize(alloc bool) int64 { @@ -832,6 +846,20 @@ func (cached *CommentOnly) CachedSize(alloc bool) int64 { } return size } +func (cached *Comments) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + size += hack.RuntimeAllocSize(int64(len(elem))) + } + return size +} func (cached *CommonTableExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -849,7 +877,7 @@ func (cached *CommonTableExpr) CachedSize(alloc bool) int64 { size += elem.CachedSize(false) } } - // field Subquery vitess.io/vitess/go/vt/sqlparser.SelectStatement + // field Subquery vitess.io/vitess/go/vt/sqlparser.TableStatement if cc, ok := cached.Subquery.(cachedObject); ok { size += cc.CachedSize(true) } @@ -1038,7 +1066,7 @@ func (cached *CreateView) CachedSize(alloc bool) int64 { size += elem.CachedSize(false) } } - // field Select vitess.io/vitess/go/vt/sqlparser.SelectStatement + // field Select vitess.io/vitess/go/vt/sqlparser.TableStatement if cc, ok := cached.Select.(cachedObject); ok { size += cc.CachedSize(true) } @@ -1168,7 +1196,7 @@ func (cached *DerivedTable) CachedSize(alloc bool) int64 { if alloc { size += int64(24) } - // field Select vitess.io/vitess/go/vt/sqlparser.SelectStatement + // field Select vitess.io/vitess/go/vt/sqlparser.TableStatement if cc, ok := cached.Select.(cachedObject); ok { size += cc.CachedSize(true) } @@ -1313,6 +1341,22 @@ func (cached *ExplainTab) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Wild))) return size } +func (cached *Exprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *ExtractFuncExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -1819,6 +1863,20 @@ func (cached *IndexHint) CachedSize(alloc bool) int64 { } return size } +func (cached *IndexHints) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *IndexInfo) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -2696,6 +2754,17 @@ func (cached *LinestrPropertyFuncExpr) CachedSize(alloc bool) int64 { } return size } +func (cached *ListArg) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += hack.RuntimeAllocSize(int64(16)) + } + size += hack.RuntimeAllocSize(int64(len(*cached))) + return size +} func (cached *Literal) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -2962,6 +3031,20 @@ func (cached *NamedWindow) CachedSize(alloc bool) int64 { } return size } +func (cached *NamedWindows) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *Nextval) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3020,6 +3103,20 @@ func (cached *Offset) CachedSize(alloc bool) int64 { } return size } +func (cached *OnDup) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *OptLike) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3064,6 +3161,20 @@ func (cached *Order) CachedSize(alloc bool) int64 { } return size } +func (cached *OrderBy) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *OrderByOption) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3297,6 +3408,20 @@ func (cached *PartitionValueRange) CachedSize(alloc bool) int64 { } return size } +func (cached *Partitions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(32)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} func (cached *PerformanceSchemaFuncExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3753,6 +3878,22 @@ func (cached *Select) CachedSize(alloc bool) int64 { size += cached.Into.CachedSize(true) return size } +func (cached *SelectExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *SelectInto) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -3810,6 +3951,20 @@ func (cached *SetExpr) CachedSize(alloc bool) int64 { } return size } +func (cached *SetExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *Show) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4095,6 +4250,20 @@ func (cached *SubPartitionDefinitionOptions) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.TableSpace))) return size } +func (cached *SubPartitionDefinitions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *Subquery) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4103,7 +4272,7 @@ func (cached *Subquery) CachedSize(alloc bool) int64 { if alloc { size += int64(16) } - // field Select vitess.io/vitess/go/vt/sqlparser.SelectStatement + // field Select vitess.io/vitess/go/vt/sqlparser.TableStatement if cc, ok := cached.Select.(cachedObject); ok { size += cc.CachedSize(true) } @@ -4161,6 +4330,36 @@ func (cached *TableAndLockType) CachedSize(alloc bool) int64 { } return size } +func (cached *TableAndLockTypes) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} +func (cached *TableExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *TableName) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4175,6 +4374,20 @@ func (cached *TableName) CachedSize(alloc bool) int64 { size += cached.Qualifier.CachedSize(false) return size } +func (cached *TableNames) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(32)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} func (cached *TableOption) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4198,6 +4411,20 @@ func (cached *TableOption) CachedSize(alloc bool) int64 { } return size } +func (cached *TableOptions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *TableSpec) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4320,11 +4547,11 @@ func (cached *Union) CachedSize(alloc bool) int64 { } // field With *vitess.io/vitess/go/vt/sqlparser.With size += cached.With.CachedSize(true) - // field Left vitess.io/vitess/go/vt/sqlparser.SelectStatement + // field Left vitess.io/vitess/go/vt/sqlparser.TableStatement if cc, ok := cached.Left.(cachedObject); ok { size += cc.CachedSize(true) } - // field Right vitess.io/vitess/go/vt/sqlparser.SelectStatement + // field Right vitess.io/vitess/go/vt/sqlparser.TableStatement if cc, ok := cached.Right.(cachedObject); ok { size += cc.CachedSize(true) } @@ -4398,6 +4625,20 @@ func (cached *UpdateExpr) CachedSize(alloc bool) int64 { } return size } +func (cached *UpdateExprs) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *UpdateXMLExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4470,6 +4711,22 @@ func (cached *VStream) CachedSize(alloc bool) int64 { size += cached.Limit.CachedSize(true) return size } +func (cached *ValTuple) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *Validation) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4480,6 +4737,27 @@ func (cached *Validation) CachedSize(alloc bool) int64 { } return size } +func (cached *Values) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(24)) + for _, elem := range *cached { + { + size += hack.RuntimeAllocSize(int64(cap(elem)) * int64(16)) + for _, elem := range elem { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + } + } + return size +} func (cached *ValuesFuncExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4492,6 +4770,45 @@ func (cached *ValuesFuncExpr) CachedSize(alloc bool) int64 { size += cached.Name.CachedSize(true) return size } +func (cached *ValuesStatement) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(96) + } + // field With *vitess.io/vitess/go/vt/sqlparser.With + size += cached.With.CachedSize(true) + // field Rows vitess.io/vitess/go/vt/sqlparser.Values + { + size += hack.RuntimeAllocSize(int64(cap(cached.Rows)) * int64(24)) + for _, elem := range cached.Rows { + { + size += hack.RuntimeAllocSize(int64(cap(elem)) * int64(16)) + for _, elem := range elem { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + } + } + } + // field ListArg vitess.io/vitess/go/vt/sqlparser.ListArg + size += hack.RuntimeAllocSize(int64(len(cached.ListArg))) + // field Comments *vitess.io/vitess/go/vt/sqlparser.ParsedComments + size += cached.Comments.CachedSize(true) + // field Order vitess.io/vitess/go/vt/sqlparser.OrderBy + { + size += hack.RuntimeAllocSize(int64(cap(cached.Order)) * int64(8)) + for _, elem := range cached.Order { + size += elem.CachedSize(true) + } + } + // field Limit *vitess.io/vitess/go/vt/sqlparser.Limit + size += cached.Limit.CachedSize(true) + return size +} func (cached *VarPop) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -4649,6 +4966,20 @@ func (cached *WindowDefinition) CachedSize(alloc bool) int64 { size += cached.WindowSpec.CachedSize(true) return size } +func (cached *WindowDefinitions) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(8)) + for _, elem := range *cached { + size += elem.CachedSize(true) + } + return size +} func (cached *WindowSpecification) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/sqlparser/keywords.go b/go/vt/sqlparser/keywords.go index 5c1b881df30..2f1a220066d 100644 --- a/go/vt/sqlparser/keywords.go +++ b/go/vt/sqlparser/keywords.go @@ -430,6 +430,7 @@ var keywords = []keyword{ {"min", MIN}, {"manifest", MANIFEST}, {"master_bind", UNUSED}, + {"manual", MANUAL}, {"match", MATCH}, {"max", MAX}, {"max_rows", MAX_ROWS}, @@ -489,6 +490,7 @@ var keywords = []keyword{ {"outer", OUTER}, {"outfile", OUTFILE}, {"over", OVER}, + {"parallel", PARALLEL}, {"overwrite", OVERWRITE}, {"pack_keys", PACK_KEYS}, {"parser", PARSER}, @@ -515,6 +517,7 @@ var keywords = []keyword{ {"procedure", PROCEDURE}, {"ps_current_thread_id", PS_CURRENT_THREAD_ID}, {"ps_thread_id", PS_THREAD_ID}, + {"qualify", QUALIFY}, {"queries", QUERIES}, {"query", QUERY}, {"range", RANGE}, @@ -696,6 +699,7 @@ var keywords = []keyword{ {"system", UNUSED}, {"table", TABLE}, {"tables", TABLES}, + {"tablesample", TABLESAMPLE}, {"tablespace", TABLESPACE}, {"temporary", TEMPORARY}, {"temptable", TEMPTABLE}, diff --git a/go/vt/sqlparser/normalizer.go b/go/vt/sqlparser/normalizer.go index 48311a39a7a..02cb11e2a97 100644 --- a/go/vt/sqlparser/normalizer.go +++ b/go/vt/sqlparser/normalizer.go @@ -48,7 +48,8 @@ type normalizer struct { reserved *ReservedVars vals map[Literal]string err error - inDerived bool + inDerived int + inSelect int } func newNormalizer(reserved *ReservedVars, bindVars map[string]*querypb.BindVariable) *normalizer { @@ -64,30 +65,43 @@ func (nz *normalizer) walkStatementUp(cursor *Cursor) bool { if nz.err != nil { return false } - node, isLiteral := cursor.Node().(*Literal) - if !isLiteral { - return true + switch node := cursor.node.(type) { + case *DerivedTable: + nz.inDerived-- + case *Select: + nz.inSelect-- + case *Literal: + if nz.inSelect == 0 { + nz.convertLiteral(node, cursor) + return nz.err == nil + } + parent := cursor.Parent() + switch parent.(type) { + case *Order, *GroupBy: + return true + case *Limit: + nz.convertLiteral(node, cursor) + default: + nz.convertLiteralDedup(node, cursor) + } } - nz.convertLiteral(node, cursor) return nz.err == nil // only continue if we haven't found any errors } // walkStatementDown is the top level walk function. // If it encounters a Select, it switches to a mode // where variables are deduped. -func (nz *normalizer) walkStatementDown(node, parent SQLNode) bool { +func (nz *normalizer) walkStatementDown(node, _ SQLNode) bool { switch node := node.(type) { // no need to normalize the statement types case *Set, *Show, *Begin, *Commit, *Rollback, *Savepoint, DDLStatement, *SRollback, *Release, *OtherAdmin, *Analyze: return false + case *DerivedTable: + nz.inDerived++ case *Select: - _, isDerived := parent.(*DerivedTable) - var tmp bool - tmp, nz.inDerived = nz.inDerived, isDerived - _ = SafeRewrite(node, nz.walkDownSelect, nz.walkUpSelect) - // Don't continue - nz.inDerived = tmp - return false + nz.inSelect++ + case SelectExprs: + return nz.inDerived == 0 case *ComparisonExpr: nz.convertComparison(node) case *UpdateExpr: @@ -98,62 +112,9 @@ func (nz *normalizer) walkStatementDown(node, parent SQLNode) bool { return false case *ConvertType: // we should not rewrite the type description return false - } - return nz.err == nil // only continue if we haven't found any errors -} - -// walkDownSelect normalizes the AST in Select mode. -func (nz *normalizer) walkDownSelect(node, parent SQLNode) bool { - switch node := node.(type) { - case *Select: - _, isDerived := parent.(*DerivedTable) - if !isDerived { - return true - } - var tmp bool - tmp, nz.inDerived = nz.inDerived, isDerived - // initiating a new AST walk here means that we might change something while walking down on the tree, - // but since we are only changing literals, we can be safe that we are not changing the SELECT struct, - // only something much further down, and that should be safe - _ = SafeRewrite(node, nz.walkDownSelect, nz.walkUpSelect) - // Don't continue - nz.inDerived = tmp - return false - case SelectExprs: - return !nz.inDerived - case *ComparisonExpr: - nz.convertComparison(node) case *FramePoint: // do not make a bind var for rows and range return false - case *ColName, TableName: - // Common node types that never contain Literals or ListArgs but create a lot of object - // allocations. - return false - case *ConvertType: - // we should not rewrite the type description - return false - } - return nz.err == nil // only continue if we haven't found any errors -} - -// walkUpSelect normalizes the Literals in Select mode. -func (nz *normalizer) walkUpSelect(cursor *Cursor) bool { - if nz.err != nil { - return false - } - node, isLiteral := cursor.Node().(*Literal) - if !isLiteral { - return true - } - parent := cursor.Parent() - switch parent.(type) { - case *Order, *GroupBy: - return true - case *Limit: - nz.convertLiteral(node, cursor) - default: - nz.convertLiteralDedup(node, cursor) } return nz.err == nil // only continue if we haven't found any errors } diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index d3d5fd469e7..5e075d51baa 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -3868,7 +3868,22 @@ var ( }, { input: `select * from tbl where foo > any (select foo from tbl2)`, }, { - input: `select * from tbl where foo > all (select foo from tbl2)`}} + input: `select * from tbl where foo > all (select foo from tbl2)`, + }, { + input: "insert into t1(a1) values row('a'), row('b')", + }, { + input: "insert into t1(a1) values ('a'), ('b')", + }, { + input: "values row('a'), row('b')", + }, { + input: "values /*my comment*/ row('a'), row('b')", + }, { + input: `with x as (select * from t1 limit 1) values ROW('a1', (select x.a1 from x))`, + output: "with x as (select * from t1 limit 1) values row('a1', (select x.a1 from x))", + }, { + input: "SELECT 1,2 UNION SELECT * from (VALUES ROW(10,15)) t", + output: "select 1, 2 from dual union select * from (values row(10, 15)) as t", + }} ) func TestValid(t *testing.T) { @@ -3944,6 +3959,12 @@ func TestInvalid(t *testing.T) { }, { input: "/*!*/", err: "Query was empty", + }, { + input: "values row(1) into outfile s3 'out_file_name'", + err: "VALUES does not support INTO at position 46", + }, { + input: "values row(1) lock in share mode", + err: "VALUES does not support LOCK at position 33", }, { input: "select /* union with limit on lhs */ 1 from t limit 1 union select 1 from t", err: "syntax error at position 60 near 'union'", @@ -6204,6 +6225,12 @@ var ( }, { input: "create database test_db default encryption @a", output: "syntax error at position 46 near 'a'", + }, { + input: "select * from t1 where a1 in row('a')", + output: "syntax error at position 33 near 'row'", + }, { + input: "insert into t1 (a1) values row('a'), ('b')", + output: "syntax error at position 39", }} ) diff --git a/go/vt/sqlparser/parsed_query.go b/go/vt/sqlparser/parsed_query.go index 491e7400988..0e3f9801610 100644 --- a/go/vt/sqlparser/parsed_query.go +++ b/go/vt/sqlparser/parsed_query.go @@ -101,6 +101,14 @@ func EncodeValue(buf *strings.Builder, value *querypb.BindVariable) { sqltypes.ProtoToValue(bv).EncodeSQLStringBuilder(buf) } buf.WriteByte(')') + case querypb.Type_ROW_TUPLE: + for i, bv := range value.Values { + if i != 0 { + buf.WriteString(", ") + } + buf.WriteString("row") + sqltypes.ProtoToValue(bv).EncodeSQLStringBuilder(buf) + } case querypb.Type_RAW: v, _ := sqltypes.BindVariableToValue(value) buf.Write(v.Raw()) @@ -123,7 +131,9 @@ func FetchBindVar(name string, bindVariables map[string]*querypb.BindVariable) ( } if isList { - if supplied.Type != querypb.Type_TUPLE { + switch supplied.Type { + case querypb.Type_TUPLE, querypb.Type_ROW_TUPLE: + default: return nil, false, fmt.Errorf("unexpected list arg type (%v) for key %s", supplied.Type, name) } if len(supplied.Values) == 0 { diff --git a/go/vt/sqlparser/parsed_query_test.go b/go/vt/sqlparser/parsed_query_test.go index 1458a3e6527..26b9855b0f0 100644 --- a/go/vt/sqlparser/parsed_query_test.go +++ b/go/vt/sqlparser/parsed_query_test.go @@ -103,6 +103,13 @@ func TestGenerateQuery(t *testing.T) { "vals": sqltypes.Int64BindVariable(1), }, output: "unexpected list arg type (INT64) for key vals", + }, { + desc: "row tuple", + query: "select 1 from (values ::a) dt", + bindVars: map[string]*querypb.BindVariable{ + "a": createRowTupleBV(), + }, + output: "select 1 from (values row('a', 1), row('b', 2)) as dt", }, { desc: "list bind var for non-list", query: "select * from a where id = :vals", @@ -302,3 +309,12 @@ func TestCastBindVars(t *testing.T) { }) } } + +func createRowTupleBV() *querypb.BindVariable { + v1 := sqltypes.TestTuple(sqltypes.NewVarChar("a"), sqltypes.NewInt64(1)) + v2 := sqltypes.TestTuple(sqltypes.NewVarChar("b"), sqltypes.NewInt64(2)) + return &querypb.BindVariable{ + Type: querypb.Type_ROW_TUPLE, + Values: append([]*querypb.Value{sqltypes.ValueToProto(v1)}, sqltypes.ValueToProto(v2)), + } +} diff --git a/go/vt/sqlparser/parser.go b/go/vt/sqlparser/parser.go index d4948396ae5..8af0018db2a 100644 --- a/go/vt/sqlparser/parser.go +++ b/go/vt/sqlparser/parser.go @@ -77,7 +77,7 @@ func yyParsePooled(yylex yyLexer) int { // error is ignored and the DDL is returned anyway. func (p *Parser) Parse2(sql string) (Statement, BindVars, error) { tokenizer := p.NewStringTokenizer(sql) - if yyParsePooled(tokenizer) != 0 { + if yyParsePooled(tokenizer) != 0 || tokenizer.LastError != nil { if tokenizer.partialDDL != nil { if typ, val := tokenizer.Scan(); typ != 0 { return nil, nil, fmt.Errorf("extra characters encountered after end of DDL: '%s'", val) diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index befd9b44c3b..4569fbc7686 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -705,67 +705,71 @@ const UNBOUNDED = 58012 const VCPU = 58013 const VISIBLE = 58014 const RETURNING = 58015 -const FORMAT_BYTES = 58016 -const FORMAT_PICO_TIME = 58017 -const PS_CURRENT_THREAD_ID = 58018 -const PS_THREAD_ID = 58019 -const GTID_SUBSET = 58020 -const GTID_SUBTRACT = 58021 -const WAIT_FOR_EXECUTED_GTID_SET = 58022 -const WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS = 58023 -const FORMAT = 58024 -const TREE = 58025 -const VITESS = 58026 -const TRADITIONAL = 58027 -const VTEXPLAIN = 58028 -const VEXPLAIN = 58029 -const PLAN = 58030 -const LOCAL = 58031 -const LOW_PRIORITY = 58032 -const NO_WRITE_TO_BINLOG = 58033 -const LOGS = 58034 -const ERROR = 58035 -const GENERAL = 58036 -const HOSTS = 58037 -const OPTIMIZER_COSTS = 58038 -const USER_RESOURCES = 58039 -const SLOW = 58040 -const CHANNEL = 58041 -const RELAY = 58042 -const EXPORT = 58043 -const CURRENT = 58044 -const ROW = 58045 -const ROWS = 58046 -const AVG_ROW_LENGTH = 58047 -const CONNECTION = 58048 -const CHECKSUM = 58049 -const DELAY_KEY_WRITE = 58050 -const ENCRYPTION = 58051 -const ENGINE = 58052 -const INSERT_METHOD = 58053 -const MAX_ROWS = 58054 -const MIN_ROWS = 58055 -const PACK_KEYS = 58056 -const PASSWORD = 58057 -const FIXED = 58058 -const DYNAMIC = 58059 -const COMPRESSED = 58060 -const REDUNDANT = 58061 -const COMPACT = 58062 -const ROW_FORMAT = 58063 -const STATS_AUTO_RECALC = 58064 -const STATS_PERSISTENT = 58065 -const STATS_SAMPLE_PAGES = 58066 -const STORAGE = 58067 -const MEMORY = 58068 -const DISK = 58069 -const PARTITIONS = 58070 -const LINEAR = 58071 -const RANGE = 58072 -const LIST = 58073 -const SUBPARTITION = 58074 -const SUBPARTITIONS = 58075 -const HASH = 58076 +const MANUAL = 58016 +const PARALLEL = 58017 +const QUALIFY = 58018 +const TABLESAMPLE = 58019 +const FORMAT_BYTES = 58020 +const FORMAT_PICO_TIME = 58021 +const PS_CURRENT_THREAD_ID = 58022 +const PS_THREAD_ID = 58023 +const GTID_SUBSET = 58024 +const GTID_SUBTRACT = 58025 +const WAIT_FOR_EXECUTED_GTID_SET = 58026 +const WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS = 58027 +const FORMAT = 58028 +const TREE = 58029 +const VITESS = 58030 +const TRADITIONAL = 58031 +const VTEXPLAIN = 58032 +const VEXPLAIN = 58033 +const PLAN = 58034 +const LOCAL = 58035 +const LOW_PRIORITY = 58036 +const NO_WRITE_TO_BINLOG = 58037 +const LOGS = 58038 +const ERROR = 58039 +const GENERAL = 58040 +const HOSTS = 58041 +const OPTIMIZER_COSTS = 58042 +const USER_RESOURCES = 58043 +const SLOW = 58044 +const CHANNEL = 58045 +const RELAY = 58046 +const EXPORT = 58047 +const CURRENT = 58048 +const ROW = 58049 +const ROWS = 58050 +const AVG_ROW_LENGTH = 58051 +const CONNECTION = 58052 +const CHECKSUM = 58053 +const DELAY_KEY_WRITE = 58054 +const ENCRYPTION = 58055 +const ENGINE = 58056 +const INSERT_METHOD = 58057 +const MAX_ROWS = 58058 +const MIN_ROWS = 58059 +const PACK_KEYS = 58060 +const PASSWORD = 58061 +const FIXED = 58062 +const DYNAMIC = 58063 +const COMPRESSED = 58064 +const REDUNDANT = 58065 +const COMPACT = 58066 +const ROW_FORMAT = 58067 +const STATS_AUTO_RECALC = 58068 +const STATS_PERSISTENT = 58069 +const STATS_SAMPLE_PAGES = 58070 +const STORAGE = 58071 +const MEMORY = 58072 +const DISK = 58073 +const PARTITIONS = 58074 +const LINEAR = 58075 +const RANGE = 58076 +const LIST = 58077 +const SUBPARTITION = 58078 +const SUBPARTITIONS = 58079 +const HASH = 58080 var yyToknames = [...]string{ "$end", @@ -1458,6 +1462,10 @@ var yyToknames = [...]string{ "VCPU", "VISIBLE", "RETURNING", + "MANUAL", + "PARALLEL", + "QUALIFY", + "TABLESAMPLE", "FORMAT_BYTES", "FORMAT_PICO_TIME", "PS_CURRENT_THREAD_ID", @@ -1538,249 +1546,548 @@ var yyExca = [...]int{ 17, 49, -2, 40, -1, 52, - 1, 157, - 752, 157, - -2, 165, + 1, 160, + 756, 160, + -2, 168, -1, 53, - 149, 165, - 191, 165, - 364, 165, - -2, 523, + 149, 168, + 191, 168, + 364, 168, + -2, 526, -1, 61, - 38, 784, - 254, 784, - 265, 784, - 300, 798, - 301, 798, - -2, 786, + 38, 787, + 254, 787, + 265, 787, + 300, 801, + 301, 801, + -2, 789, -1, 66, - 256, 822, - -2, 820, - -1, 122, - 253, 1621, - -2, 131, + 256, 825, + -2, 823, -1, 124, - 1, 158, - 752, 158, - -2, 165, - -1, 135, - 150, 408, - 259, 408, - -2, 512, - -1, 154, - 149, 165, - 191, 165, - 364, 165, - -2, 532, - -1, 749, + 253, 1630, + -2, 134, + -1, 126, + 1, 161, + 756, 161, + -2, 168, + -1, 137, + 150, 411, + 259, 411, + -2, 515, + -1, 156, + 149, 168, + 191, 168, + 364, 168, + -2, 535, + -1, 755, 177, 41, -2, 43, - -1, 958, - 95, 1638, - -2, 1482, - -1, 959, - 95, 1639, - 236, 1643, - -2, 1483, - -1, 960, - 236, 1642, + -1, 964, + 95, 1647, + -2, 1485, + -1, 965, + 95, 1648, + 236, 1652, + -2, 1486, + -1, 966, + 236, 1651, -2, 42, - -1, 1044, - 65, 896, - -2, 909, - -1, 1132, - 264, 1109, - 269, 1109, - -2, 419, - -1, 1217, - 1, 580, - 752, 580, - -2, 165, - -1, 1528, - 236, 1643, - -2, 1483, - -1, 1740, - 65, 897, - -2, 913, - -1, 1741, - 65, 898, - -2, 914, - -1, 1801, - 149, 165, - 191, 165, - 364, 165, - -2, 458, - -1, 1884, - 150, 408, - 259, 408, - -2, 512, - -1, 1893, - 264, 1110, - 269, 1110, - -2, 420, - -1, 2342, - 236, 1647, - -2, 1641, - -1, 2343, - 236, 1643, - -2, 1639, - -1, 2446, - 149, 165, - 191, 165, - 364, 165, - -2, 459, - -1, 2453, - 28, 186, - -2, 188, - -1, 2917, - 86, 96, - 96, 96, - -2, 976, - -1, 2985, - 727, 702, - -2, 676, - -1, 3210, - 55, 1586, - -2, 1580, - -1, 4047, - 727, 702, - -2, 690, - -1, 4139, - 98, 634, - 104, 634, - 114, 634, - 193, 634, - 194, 634, - 195, 634, - 196, 634, - 197, 634, - 198, 634, - 199, 634, - 200, 634, - 201, 634, - 202, 634, - 203, 634, - 204, 634, - 205, 634, - 206, 634, - 207, 634, - 208, 634, - 209, 634, - 210, 634, - 211, 634, - 212, 634, - 213, 634, - 214, 634, - 215, 634, - 216, 634, - 217, 634, - 218, 634, - 219, 634, - 220, 634, - 221, 634, - 222, 634, - 223, 634, - 224, 634, - 225, 634, - 226, 634, - 227, 634, - 228, 634, - 229, 634, - 230, 634, - 231, 634, - 232, 634, - 233, 634, - 234, 634, - -2, 2019, + -1, 1052, + 65, 899, + -2, 912, + -1, 1141, + 264, 1112, + 269, 1112, + -2, 422, + -1, 1226, + 1, 583, + 756, 583, + -2, 168, + -1, 1537, + 236, 1652, + -2, 1486, + -1, 1750, + 65, 900, + -2, 916, + -1, 1751, + 65, 901, + -2, 917, + -1, 1816, + 149, 168, + 191, 168, + 364, 168, + -2, 461, + -1, 1899, + 150, 411, + 259, 411, + -2, 515, + -1, 1908, + 264, 1113, + 269, 1113, + -2, 423, + -1, 2357, + 236, 1656, + -2, 1650, + -1, 2358, + 236, 1652, + -2, 1648, + -1, 2463, + 149, 168, + 191, 168, + 364, 168, + -2, 462, + -1, 2470, + 28, 189, + -2, 191, + -1, 2936, + 86, 99, + 96, 99, + -2, 979, + -1, 3004, + 731, 705, + -2, 679, + -1, 3229, + 55, 1589, + -2, 1583, + -1, 4066, + 731, 705, + -2, 693, + -1, 4158, + 98, 637, + 104, 637, + 114, 637, + 193, 637, + 194, 637, + 195, 637, + 196, 637, + 197, 637, + 198, 637, + 199, 637, + 200, 637, + 201, 637, + 202, 637, + 203, 637, + 204, 637, + 205, 637, + 206, 637, + 207, 637, + 208, 637, + 209, 637, + 210, 637, + 211, 637, + 212, 637, + 213, 637, + 214, 637, + 215, 637, + 216, 637, + 217, 637, + 218, 637, + 219, 637, + 220, 637, + 221, 637, + 222, 637, + 223, 637, + 224, 637, + 225, 637, + 226, 637, + 227, 637, + 228, 637, + 229, 637, + 230, 637, + 231, 637, + 232, 637, + 233, 637, + 234, 637, + -2, 2029, } const yyPrivate = 57344 -const yyLast = 57002 +const yyLast = 56577 var yyAct = [...]int{ - 974, 3698, 3699, 87, 3697, 4137, 4214, 4028, 4118, 3361, - 4227, 4181, 4106, 3647, 4182, 969, 1285, 961, 3262, 2135, - 2014, 2443, 2170, 3269, 2371, 1283, 3497, 4010, 2147, 3933, - 3319, 3310, 3324, 3321, 3320, 3318, 3323, 3322, 2073, 3223, - 4008, 5, 3634, 2373, 3161, 3076, 3339, 3277, 2518, 753, - 3338, 3227, 3224, 3543, 962, 3221, 3740, 3050, 3537, 923, - 747, 3211, 2877, 3075, 1804, 2398, 2481, 781, 2414, 1760, - 748, 2951, 4079, 3032, 3368, 1861, 3527, 2417, 2982, 922, - 3341, 2505, 2486, 3565, 2952, 2549, 1042, 1164, 87, 163, - 1094, 927, 2953, 2431, 42, 1062, 1039, 743, 2883, 1069, - 1909, 2902, 2419, 2869, 41, 2418, 2853, 1042, 2327, 2294, - 2169, 2295, 2131, 3023, 2527, 149, 43, 1891, 2504, 2081, - 2406, 2488, 1104, 2944, 1122, 2566, 1127, 1793, 2919, 1773, - 2421, 1721, 2890, 1541, 2175, 100, 2106, 2095, 104, 105, - 1466, 1449, 1898, 2010, 1101, 1098, 3226, 763, 1133, 1870, - 1102, 2477, 1990, 1128, 1130, 1129, 2478, 1792, 1079, 1778, - 1081, 1051, 758, 1140, 750, 2399, 1743, 2183, 3735, 2202, - 1048, 2851, 1524, 85, 2072, 2022, 1061, 1041, 107, 1045, - 3727, 1500, 99, 1273, 167, 3554, 3498, 1883, 127, 125, - 126, 132, 1046, 1213, 1037, 133, 924, 1049, 1064, 751, - 1074, 84, 1545, 98, 1047, 106, 4215, 1281, 3635, 3307, - 1259, 740, 1073, 93, 2520, 2521, 2522, 4063, 1550, 2520, - 3005, 3004, 2564, 2973, 3627, 1036, 4164, 683, 3040, 3590, - 3041, 4059, 2368, 2369, 4058, 1054, 2088, 128, 2087, 1166, - 2086, 134, 2085, 4064, 1169, 2084, 1095, 3329, 2083, 2053, - 1229, 4158, 1183, 1184, 1185, 2849, 1188, 1189, 1190, 1191, - 3326, 2618, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, - 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1088, - 3207, 4185, 1089, 1055, 741, 2, 680, 1040, 681, 1764, - 1038, 1143, 95, 1975, 1119, 2553, 1762, 3702, 3702, 3329, - 1144, 2879, 4220, 725, 3165, 1111, 2392, 3327, 4237, 128, - 1170, 1173, 1174, 1118, 1117, 1116, 95, 4037, 95, 1765, - 1063, 1463, 1177, 1106, 1460, 2975, 1763, 4219, 4180, 1230, - 111, 112, 113, 1186, 116, 4059, 3333, 122, 725, 2552, - 191, 1483, 95, 675, 4205, 3501, 928, 3500, 4168, 4166, - 1035, 2395, 2394, 2995, 2998, 738, 739, 190, 4011, 3327, - 719, 1754, 2109, 2814, 2093, 1030, 1031, 1032, 1033, 1087, - 1091, 926, 1044, 4167, 4165, 3387, 4133, 128, 3929, 3928, - 129, 1168, 190, 1167, 977, 978, 979, 719, 3333, 977, - 978, 979, 3640, 3701, 3701, 3641, 172, 1451, 4195, 3939, - 1076, 1077, 1120, 4147, 86, 129, 1087, 1091, 926, 4162, - 3659, 3648, 4107, 4115, 2546, 86, 86, 3938, 719, 2625, - 2140, 172, 4142, 4145, 3413, 1872, 3012, 2850, 3013, 1462, - 714, 3259, 3260, 4151, 4152, 2551, 2438, 2439, 4119, 2893, - 3258, 1479, 2933, 3279, 3280, 1794, 1115, 1795, 1222, 1223, - 4146, 3330, 2065, 2066, 3039, 719, 169, 3658, 2928, 170, - 2622, 2927, 2437, 3022, 2929, 1278, 3754, 2894, 1254, 1255, - 1249, 1028, 1110, 1027, 1237, 1112, 4029, 2940, 699, 1238, - 1225, 169, 1250, 1243, 170, 189, 2018, 95, 719, 2623, - 1480, 697, 1481, 1482, 2456, 2455, 3365, 1212, 95, 95, - 719, 3395, 1237, 3330, 1113, 2370, 719, 1238, 3363, 4042, - 189, 2886, 2887, 1444, 4123, 1236, 2616, 1235, 3393, 4123, - 2068, 1790, 2064, 733, 737, 731, 3097, 3369, 2528, 3024, - 1187, 694, 1996, 1725, 1461, 4186, 3981, 3356, 3982, 2983, - 709, 3008, 2567, 2402, 2573, 3357, 1965, 86, 4217, 2592, - 88, 2593, 3278, 2594, 1991, 704, 4187, 1266, 1270, 1268, - 1450, 1252, 1253, 2569, 3281, 1443, 1275, 707, 2211, 1218, - 717, 1258, 2497, 3027, 1115, 720, 1107, 1256, 718, 1277, - 3913, 1251, 1244, 1109, 1108, 1276, 2619, 1257, 2620, 1501, - 1966, 3629, 1967, 3366, 3628, 2595, 2491, 1265, 1267, 2574, - 173, 1080, 720, 3625, 1142, 3364, 1142, 1193, 1192, 179, - 1153, 3384, 1151, 1502, 1503, 1504, 1505, 1506, 1507, 1508, - 1510, 1509, 1511, 1512, 2531, 173, 1728, 1123, 2019, 2571, - 95, 1124, 1113, 720, 179, 3281, 3706, 1114, 684, 2415, - 686, 700, 1124, 722, 1162, 721, 690, 1161, 688, 692, - 701, 693, 1160, 687, 4159, 698, 1159, 1158, 689, 702, - 703, 706, 710, 711, 712, 708, 705, 2203, 696, 723, - 720, 2570, 2205, 1157, 1156, 1155, 2210, 2206, 1150, 1876, - 2207, 2208, 2209, 1163, 2572, 2204, 2212, 2213, 2214, 2215, - 2216, 2217, 2218, 2219, 2220, 3098, 3540, 1099, 1090, 1084, - 1082, 1099, 1136, 720, 2976, 1097, 4238, 1141, 1263, 1141, - 4192, 1099, 1264, 1075, 1282, 720, 1282, 1282, 3624, 3164, - 1135, 720, 1269, 2580, 2576, 2578, 2579, 2577, 2581, 2582, - 2583, 2584, 2011, 1871, 3028, 1090, 1084, 1082, 164, 2400, - 2401, 2557, 3173, 2556, 2007, 1452, 1180, 1262, 3192, 2490, - 3190, 3301, 2000, 1791, 1998, 1999, 1997, 2001, 2002, 2003, - 1154, 3007, 1152, 164, 1869, 1114, 1042, 1525, 1530, 1531, - 1868, 1534, 1536, 1537, 1538, 1539, 1540, 1867, 1543, 1544, - 1546, 1546, 3010, 1546, 1546, 1551, 1551, 1551, 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, + 980, 3716, 975, 87, 4246, 2162, 3717, 4233, 3718, 3380, + 4125, 968, 4137, 4200, 3281, 967, 4201, 2150, 4047, 3516, + 2460, 3288, 1292, 4156, 2386, 3952, 3242, 4029, 3338, 2185, + 3343, 3340, 3339, 3337, 3342, 1819, 3341, 4027, 3653, 2388, + 1294, 3666, 3095, 3358, 2029, 4098, 3296, 3329, 2088, 3180, + 2535, 5, 3357, 759, 3246, 3243, 3562, 3556, 3759, 3069, + 3094, 2896, 3230, 2498, 754, 2434, 3051, 1770, 929, 787, + 3546, 3387, 933, 753, 928, 42, 3360, 3001, 2970, 2522, + 2503, 2415, 3584, 2971, 2566, 1103, 1050, 2972, 87, 165, + 2448, 2431, 1876, 2921, 1071, 1924, 1047, 2436, 2902, 1078, + 2435, 1149, 3240, 2886, 749, 1173, 2870, 2310, 41, 1050, + 43, 2342, 2146, 2184, 2544, 3042, 151, 2309, 1906, 2096, + 2521, 2423, 2583, 2505, 1113, 2963, 1136, 1808, 1131, 2938, + 982, 1788, 1774, 102, 1550, 2190, 2438, 106, 1731, 107, + 2121, 2110, 1475, 1458, 2025, 1913, 3245, 1110, 1107, 769, + 1070, 1142, 1885, 2909, 1111, 2005, 756, 2494, 1049, 1137, + 1053, 1139, 1138, 1807, 1088, 1793, 1090, 101, 3754, 2198, + 2217, 2868, 2495, 1059, 1753, 1533, 109, 1509, 2087, 1282, + 3746, 1073, 2416, 3573, 1056, 764, 2037, 85, 169, 129, + 127, 128, 3517, 1898, 1045, 134, 1054, 135, 1055, 757, + 1222, 1083, 1057, 930, 1554, 100, 4234, 1290, 3654, 3326, + 1268, 4082, 2537, 84, 1082, 93, 1559, 2537, 2538, 2539, + 3024, 3023, 108, 2992, 2581, 1476, 3646, 4183, 1044, 3609, + 1776, 3059, 3060, 4078, 4077, 1063, 2103, 4083, 746, 1990, + 1153, 130, 2102, 2101, 689, 2100, 1178, 136, 1104, 2099, + 2098, 2383, 2384, 2068, 1238, 686, 2866, 687, 2635, 1175, + 3226, 2570, 1186, 4177, 4204, 3184, 4256, 3721, 4199, 3721, + 1064, 4224, 1192, 1193, 1194, 3520, 1197, 1198, 1199, 1200, + 2898, 3519, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, + 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1048, + 1152, 1098, 2407, 2412, 1097, 2569, 731, 1046, 1239, 1061, + 2, 747, 4239, 1128, 4056, 130, 1127, 1126, 1125, 1179, + 1182, 1183, 3348, 1779, 1072, 1115, 1772, 2994, 3348, 1472, + 1764, 2411, 1469, 1486, 1492, 1120, 3017, 4238, 731, 4078, + 4030, 3345, 725, 2831, 1777, 2108, 981, 4187, 3406, 4152, + 3948, 3947, 1195, 1780, 113, 114, 115, 1043, 118, 1177, + 1176, 124, 192, 3720, 193, 3720, 3014, 681, 984, 985, + 986, 4214, 4186, 95, 1778, 1096, 1100, 932, 3958, 744, + 745, 4185, 3346, 130, 1129, 131, 4181, 725, 3346, 1038, + 1039, 1040, 1041, 3678, 3667, 1460, 1052, 984, 985, 986, + 4126, 174, 4134, 1096, 1100, 932, 4184, 3659, 2563, 3957, + 3660, 3352, 86, 2155, 4161, 3432, 1887, 3352, 3278, 3279, + 2455, 2456, 4138, 2867, 725, 2947, 1085, 1086, 2946, 3277, + 720, 2948, 3031, 3058, 3032, 4166, 2639, 1471, 86, 2080, + 2081, 1809, 3041, 1810, 2454, 2642, 1482, 2952, 1258, 1474, + 86, 1036, 725, 1035, 1287, 4164, 4048, 1246, 3677, 2995, + 1259, 171, 1247, 97, 172, 4170, 4171, 1263, 1264, 2033, + 2514, 2959, 1252, 2912, 3414, 3298, 3299, 725, 705, 2473, + 2472, 3412, 4165, 1489, 3384, 1490, 1491, 1488, 1453, 3773, + 191, 703, 2633, 2568, 2508, 95, 739, 1246, 4142, 2905, + 2906, 2913, 1247, 3382, 1124, 86, 1231, 1232, 88, 725, + 1245, 2226, 1244, 2079, 2083, 2640, 743, 737, 4205, 1476, + 725, 95, 725, 1805, 3388, 3116, 3349, 4142, 2385, 1221, + 3043, 700, 3349, 95, 1735, 4000, 1980, 4001, 1234, 4206, + 715, 3002, 1470, 2545, 3027, 3375, 2609, 4236, 2610, 2588, + 2611, 1196, 1275, 3376, 1277, 710, 97, 726, 1459, 1260, + 2584, 2590, 1122, 2419, 2006, 2419, 1279, 713, 1286, 1452, + 723, 1253, 3046, 1284, 1285, 1227, 1265, 1267, 724, 3648, + 1981, 3385, 1982, 3647, 3297, 2612, 1266, 2636, 95, 2637, + 1202, 2587, 1274, 1276, 1261, 1262, 3300, 1151, 1201, 2586, + 3383, 3932, 726, 3644, 2589, 175, 1162, 1089, 1160, 1132, + 2218, 2034, 2548, 1133, 181, 2220, 2591, 1738, 3725, 2225, + 2221, 3300, 1151, 2222, 2223, 2224, 2432, 1486, 2219, 2227, + 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 690, 726, + 692, 706, 1133, 728, 1171, 727, 696, 2507, 694, 698, + 707, 699, 1170, 693, 1169, 704, 1168, 1510, 695, 708, + 709, 712, 716, 717, 718, 714, 711, 726, 702, 729, + 4178, 1167, 1166, 3559, 1165, 1164, 1159, 1891, 1172, 3403, + 3183, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1519, 1518, + 1520, 1521, 726, 1108, 3117, 1123, 4257, 1524, 1145, 4211, + 1150, 1108, 1144, 1272, 1099, 1093, 1091, 1273, 2597, 2593, + 2595, 2596, 2594, 2598, 2599, 2600, 2601, 1278, 3643, 2026, + 1291, 1886, 1291, 1291, 726, 1150, 1108, 1084, 3047, 2574, + 1106, 2573, 1099, 1093, 1091, 726, 2022, 726, 1461, 1189, + 1482, 3211, 1271, 166, 3320, 3026, 1481, 1478, 1479, 1480, + 1485, 1487, 1484, 1884, 1483, 1806, 1163, 3012, 1161, 2417, + 2418, 2417, 2418, 1883, 1477, 2996, 3209, 1882, 2023, 1880, + 1237, 680, 1050, 1534, 1539, 1540, 4179, 1543, 1545, 1546, + 1547, 1548, 1549, 3063, 1552, 1553, 1555, 1555, 3029, 1555, + 1555, 1560, 1560, 1560, 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, 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, 4055, 1449, + 1280, 1531, 1687, 1130, 1689, 1690, 1691, 1692, 1693, 1450, + 1451, 2993, 3607, 3608, 1544, 1776, 1560, 1560, 1560, 1560, + 1560, 1560, 1992, 1991, 1993, 1994, 1995, 3719, 730, 3719, + 4140, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, + 1709, 1710, 1711, 1712, 1713, 1527, 1528, 1529, 1530, 721, + 4169, 3676, 1243, 2567, 1225, 1541, 1535, 3016, 2961, 4140, + 89, 2511, 167, 3560, 722, 1092, 4139, 95, 4101, 179, + 1524, 1556, 1912, 1557, 1558, 2871, 2873, 94, 2565, 1242, + 1468, 1248, 1249, 1250, 1251, 3350, 3351, 1230, 1561, 1562, + 1726, 3350, 3351, 1092, 4168, 4139, 2641, 1233, 3354, 2640, + 3504, 3015, 2512, 94, 3354, 1288, 1289, 3050, 1151, 2510, + 187, 4043, 1728, 3040, 1763, 94, 3039, 3598, 1734, 3580, + 1481, 1478, 1479, 1480, 1485, 1487, 1484, 1050, 1483, 4250, + 1181, 1050, 3192, 1724, 1525, 1526, 1144, 1050, 1477, 1119, + 1180, 2943, 1121, 2513, 1151, 2908, 1256, 2843, 2158, 1797, + 1688, 1236, 3191, 2509, 2903, 688, 2657, 168, 173, 170, + 176, 177, 178, 180, 182, 183, 184, 185, 126, 1725, + 94, 2010, 2461, 186, 188, 189, 190, 1524, 1521, 3276, + 3404, 1911, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1519, + 1518, 1520, 1521, 2011, 2668, 1151, 1764, 1269, 2199, 1742, + 2038, 1504, 1067, 1746, 1283, 4069, 1241, 1174, 121, 1049, + 3639, 1150, 3572, 2585, 2092, 2200, 1124, 1220, 1516, 1517, + 1519, 1518, 1520, 1521, 1744, 2019, 1745, 1811, 106, 3090, + 107, 2191, 1694, 1695, 1696, 1697, 1698, 1699, 2191, 1725, + 2677, 1124, 2527, 1116, 1490, 1491, 4215, 1150, 1188, 2872, + 1118, 1117, 1732, 1144, 1147, 1148, 1491, 1108, 3768, 4207, + 4061, 1141, 1145, 1510, 2557, 3614, 3613, 109, 3070, 2552, + 3053, 1921, 1775, 1492, 1920, 3052, 1740, 1910, 3053, 2557, + 2668, 1224, 1140, 3052, 2562, 2564, 122, 1511, 1512, 1513, + 1514, 1515, 1516, 1517, 1519, 1518, 1520, 1521, 1150, 1122, + 2560, 1162, 1766, 1154, 1144, 1904, 1160, 2561, 1156, 1062, + 3599, 4252, 1157, 1155, 1888, 1889, 1890, 3940, 2114, 2115, + 2647, 2648, 2559, 1743, 3939, 1975, 2007, 3284, 2008, 1914, + 1914, 2009, 1897, 1158, 4258, 1926, 1151, 1927, 3930, 1929, + 1931, 1769, 1741, 1935, 1937, 1939, 1941, 1943, 1916, 1957, + 1048, 1046, 3072, 1729, 2197, 1270, 4102, 2031, 2039, 1291, + 1240, 4248, 1255, 1226, 4249, 3962, 4247, 1802, 1803, 1151, + 95, 1151, 4035, 1257, 1915, 1492, 731, 1764, 3285, 1871, + 2347, 1965, 1966, 2126, 2344, 2196, 2000, 1971, 1972, 3690, + 2124, 1223, 1492, 2346, 3673, 1879, 3674, 2127, 1522, 1523, + 2125, 2182, 1998, 3287, 1987, 4103, 2714, 1123, 1894, 979, + 1895, 3689, 1893, 2015, 1907, 2013, 2014, 2012, 2016, 2017, + 2018, 4036, 1489, 3282, 1490, 1491, 3082, 3081, 3080, 3621, + 4259, 3074, 1123, 3078, 3620, 3073, 1918, 3071, 3610, 1150, + 3327, 1747, 3076, 3298, 3299, 1144, 1147, 1148, 3316, 1108, + 3283, 3075, 1961, 1141, 1145, 1492, 2968, 1999, 2027, 2967, + 192, 1492, 2966, 1953, 2517, 2001, 1956, 1492, 1958, 2182, + 3077, 3079, 1150, 1997, 1150, 1986, 1187, 1154, 1144, 1985, + 1184, 1984, 1156, 131, 3289, 1764, 1157, 1155, 1983, 3421, + 984, 985, 986, 1492, 1973, 130, 1127, 1126, 1125, 174, + 2174, 2163, 2164, 2165, 2166, 2176, 2167, 2168, 2169, 2181, + 2177, 2170, 2171, 2178, 2179, 2180, 2172, 2173, 2175, 2424, + 2425, 2044, 1967, 1964, 1489, 1963, 1490, 1491, 1962, 1291, + 1291, 1933, 1739, 3092, 2347, 2040, 2041, 2666, 3604, 2066, + 731, 1489, 3379, 1490, 1491, 87, 1455, 2665, 87, 2045, + 1805, 4208, 3297, 4220, 1764, 1764, 2052, 2053, 2054, 171, + 1764, 4057, 172, 4064, 3300, 1510, 2065, 3062, 2174, 2163, + 2164, 2165, 2166, 2176, 2167, 2168, 2169, 2181, 2177, 2170, + 2171, 2178, 2179, 2180, 2172, 2173, 2175, 3967, 191, 1511, + 1512, 1513, 1514, 1515, 1516, 1517, 1519, 1518, 1520, 1521, + 2950, 1510, 731, 2533, 1489, 2532, 1490, 1491, 2153, 2153, + 1489, 1492, 1490, 1491, 4063, 1782, 1489, 42, 1490, 1491, + 42, 2151, 2151, 2718, 2154, 1511, 1512, 1513, 1514, 1515, + 1516, 1517, 1519, 1518, 1520, 1521, 2114, 2115, 2112, 2113, + 2116, 2042, 1489, 4039, 1490, 1491, 1510, 2531, 2046, 2530, + 2048, 2049, 2050, 2051, 2529, 1726, 2528, 2055, 2892, 4235, + 4195, 1764, 1510, 2111, 1783, 1506, 4038, 1507, 2237, 2067, + 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1519, 1518, 1520, + 1521, 1508, 1522, 1523, 1505, 3286, 1511, 1512, 1513, 1514, + 1515, 1516, 1517, 1519, 1518, 1520, 1521, 4037, 1724, 3935, + 1492, 3919, 2251, 175, 1514, 1515, 1516, 1517, 1519, 1518, + 1520, 1521, 181, 1512, 1513, 1514, 1515, 1516, 1517, 1519, + 1518, 1520, 1521, 2892, 1764, 3966, 2093, 3918, 2716, 85, + 1488, 1764, 85, 3767, 1725, 2123, 2073, 2074, 1488, 1764, + 3923, 2186, 3765, 1510, 2129, 2656, 2131, 2132, 2133, 2134, + 2135, 2136, 2138, 2140, 2141, 2142, 2143, 2144, 2145, 3686, + 1489, 1492, 1490, 1491, 2128, 1492, 1723, 1511, 1512, 1513, + 1514, 1515, 1516, 1517, 1519, 1518, 1520, 1521, 2892, 4133, + 2892, 4112, 2334, 2335, 2336, 2337, 2338, 1722, 2130, 1721, + 2157, 2355, 4218, 1764, 1492, 3618, 2261, 3603, 1492, 2359, + 3389, 103, 2362, 2363, 2892, 4108, 3922, 105, 1552, 2357, + 1492, 104, 3386, 2356, 2201, 2202, 2203, 2204, 1535, 1498, + 1499, 1500, 1501, 1502, 1503, 1497, 1494, 103, 2215, 2343, + 1720, 2253, 2236, 3319, 2345, 1718, 2192, 104, 2380, 3318, + 1716, 166, 3044, 1717, 1715, 2977, 1719, 4020, 1764, 1489, + 112, 1490, 1491, 4148, 1764, 112, 2964, 2410, 1764, 1492, + 1720, 111, 1714, 110, 3657, 4054, 111, 2630, 110, 3943, + 1764, 105, 1764, 3665, 1492, 2892, 3931, 3657, 1764, 2892, + 3655, 2354, 2622, 2440, 2360, 2361, 4146, 1764, 2557, 1764, + 4144, 1764, 1492, 3578, 1764, 105, 1492, 2939, 1764, 106, + 2355, 107, 4013, 1764, 2798, 1764, 3309, 3308, 3306, 3307, + 1489, 2621, 1490, 1491, 1489, 2579, 1490, 1491, 2357, 2578, + 2470, 106, 2429, 107, 3304, 3305, 2889, 3290, 2390, 2402, + 2414, 3294, 2122, 2391, 1492, 2069, 1764, 2939, 3293, 1492, + 105, 1764, 3003, 1489, 1492, 1490, 1491, 1489, 2035, 1490, + 1491, 4011, 1764, 3304, 3303, 2442, 1113, 2918, 1764, 1489, + 1764, 1490, 1491, 2640, 3025, 2940, 4008, 1764, 1875, 3006, + 2999, 3000, 3295, 2378, 2396, 2942, 2397, 3291, 2892, 2891, + 1063, 1492, 3292, 2465, 3990, 1764, 2464, 1996, 3545, 1764, + 1113, 1988, 2479, 2480, 2481, 2482, 1978, 2474, 1974, 2475, + 2476, 2477, 2478, 2446, 2887, 2940, 2982, 2403, 1489, 1970, + 1490, 1491, 1492, 2484, 2500, 2640, 2486, 2487, 2488, 2489, + 2156, 1764, 2405, 1489, 2468, 1490, 1491, 4209, 111, 2546, + 1969, 3538, 1764, 3575, 2506, 1968, 3535, 1764, 1875, 1874, + 2427, 1489, 1784, 1490, 1491, 1489, 1281, 1490, 1491, 2451, + 2452, 2450, 3271, 1492, 1817, 1816, 2469, 2467, 1492, 2917, + 2466, 3241, 2640, 1492, 2910, 2910, 3571, 1098, 1488, 2543, + 1097, 2558, 3571, 3533, 1764, 1492, 4096, 4068, 2516, 1492, + 167, 2892, 2918, 1489, 1153, 1490, 1491, 179, 1489, 3524, + 1490, 1491, 1492, 1489, 1914, 1490, 1491, 3306, 3214, 2453, + 2501, 3574, 1488, 1492, 3496, 1764, 2497, 1492, 2798, 2551, + 2515, 2701, 2554, 2520, 2555, 2519, 2704, 2490, 2492, 2493, + 2918, 2700, 2571, 1051, 1492, 2557, 2540, 2422, 187, 1492, + 1489, 2664, 1490, 1491, 2409, 2557, 2501, 2550, 2553, 2549, + 1492, 2918, 3571, 1768, 1152, 3494, 1764, 1492, 2381, 2156, + 3490, 1764, 2572, 2094, 2575, 3487, 1764, 2078, 2576, 2577, + 2021, 1489, 1804, 1490, 1491, 1135, 1134, 3485, 1764, 1765, + 1767, 3483, 1764, 95, 97, 168, 173, 170, 176, 177, + 178, 180, 182, 183, 184, 185, 4174, 4115, 3954, 2645, + 1771, 186, 188, 189, 190, 3481, 1764, 3920, 1050, 1050, + 1050, 1492, 1489, 2582, 1490, 1491, 95, 1489, 1492, 1490, + 1491, 3780, 1489, 3622, 1490, 1491, 3479, 1764, 1545, 1492, + 1545, 3477, 1764, 3638, 1489, 3635, 1490, 1491, 1489, 1492, + 1490, 1491, 3475, 1764, 1492, 3616, 2660, 3437, 1492, 3473, + 1764, 1489, 1492, 1490, 1491, 3436, 1492, 1877, 2615, 2499, + 1492, 3377, 1489, 3332, 1490, 1491, 1489, 1949, 1490, 1491, + 3328, 2663, 3007, 2496, 2491, 1492, 2485, 2483, 2003, 1492, + 3623, 3624, 3625, 1489, 1492, 1490, 1491, 1909, 1489, 2357, + 1490, 1491, 1905, 2356, 1873, 123, 3330, 2973, 2974, 1489, + 1492, 1490, 1491, 3471, 1764, 1225, 1489, 3381, 1490, 1491, + 3469, 1764, 2632, 3955, 2673, 3585, 3586, 1492, 2683, 4072, + 2514, 3467, 1764, 2394, 1950, 1951, 1952, 2638, 1492, 3591, + 4230, 3465, 1764, 3590, 4228, 2698, 3463, 1764, 4202, 2071, + 3461, 1764, 4076, 2646, 3459, 1764, 3956, 3995, 3457, 1764, + 1492, 2974, 3443, 1764, 3588, 1492, 2652, 2649, 2650, 2651, + 1489, 3324, 1490, 1491, 1492, 2123, 3323, 1489, 4052, 1490, + 1491, 3419, 1764, 2653, 3322, 2655, 2863, 1764, 1489, 3241, + 1490, 1491, 2986, 2616, 2658, 3260, 2659, 3259, 1489, 1492, + 1490, 1491, 2672, 1489, 1492, 1490, 1491, 1489, 1492, 1490, + 1491, 1489, 1492, 1490, 1491, 1489, 2072, 1490, 1491, 1489, + 3927, 1490, 1491, 3263, 3261, 2676, 1492, 2654, 3264, 3262, + 2861, 1764, 685, 2413, 1489, 1492, 1490, 1491, 1489, 1781, + 1490, 1491, 1492, 1489, 2400, 1490, 1491, 3579, 1065, 2624, + 2625, 1492, 2836, 1764, 2627, 3219, 2842, 2813, 1764, 1489, + 2661, 1490, 1491, 2628, 3218, 4034, 2805, 1764, 3758, 3760, + 1492, 3265, 1786, 2927, 2928, 3567, 1489, 1492, 1490, 1491, + 3228, 2712, 1492, 2830, 3626, 2020, 1034, 1489, 2874, 1490, + 1491, 2796, 1764, 3231, 3233, 2153, 2794, 1764, 3302, 1066, + 2781, 1764, 3234, 2957, 2779, 1764, 748, 1050, 2151, 1489, + 2877, 1490, 1491, 3564, 1489, 1492, 1490, 1491, 2777, 1764, + 2978, 3563, 1492, 1489, 2608, 1490, 1491, 2775, 1764, 2875, + 2199, 1492, 2915, 2916, 2773, 1764, 2607, 3627, 3628, 3629, + 2380, 2440, 2606, 1785, 1050, 2935, 1068, 2200, 1489, 2605, + 1490, 1491, 1492, 1489, 1069, 1490, 1491, 1489, 1492, 1490, + 1491, 1489, 3593, 1490, 1491, 1077, 2878, 2604, 2880, 2771, + 1764, 2603, 2122, 2602, 3540, 1489, 3397, 1490, 1491, 1076, + 2914, 1191, 1190, 1492, 1489, 2973, 1490, 1491, 3745, 3056, + 3744, 1489, 1454, 1490, 1491, 103, 2895, 2119, 2117, 2118, + 1489, 105, 1490, 1491, 42, 104, 2933, 2769, 1764, 3013, + 131, 3569, 105, 2932, 2767, 1764, 2934, 2904, 1732, 1489, + 2865, 1490, 1491, 2765, 1764, 4244, 1489, 103, 1490, 1491, + 1492, 1489, 2990, 1490, 1491, 2885, 2619, 104, 1492, 4151, + 1775, 4053, 2893, 3743, 2763, 1764, 1492, 2424, 2425, 1725, + 2761, 1764, 3950, 2953, 2907, 1492, 2890, 2960, 2962, 3011, + 1492, 1945, 3547, 3301, 1489, 2937, 1490, 1491, 1492, 2931, + 3217, 1489, 2406, 1490, 1491, 2759, 1764, 2941, 3216, 2644, + 1489, 2944, 1490, 1491, 2506, 1492, 2077, 112, 2076, 110, + 2194, 2951, 2954, 1492, 4019, 2195, 3022, 4018, 111, 111, + 110, 1489, 3998, 1490, 1491, 3766, 3764, 1489, 105, 1490, + 1491, 2965, 3755, 2976, 1946, 1947, 1948, 3763, 2979, 2980, + 3756, 1492, 2757, 1764, 3636, 3568, 3566, 3333, 2975, 2541, + 2755, 1764, 1489, 2257, 1490, 1491, 1492, 1892, 2753, 1764, + 2983, 1492, 2984, 1075, 2987, 2988, 2989, 2751, 1764, 3557, + 3019, 112, 2749, 1764, 1492, 112, 3729, 1897, 2910, 2889, + 2747, 1764, 111, 3120, 3066, 3067, 111, 2702, 110, 2392, + 1492, 3008, 3009, 4232, 4231, 1492, 1798, 2742, 1764, 1489, + 1790, 1490, 1491, 116, 117, 3536, 3018, 1489, 4232, 1490, + 1491, 1492, 4231, 4040, 3602, 1489, 1492, 1490, 1491, 3086, + 2091, 3, 2089, 10, 1489, 9, 1490, 1491, 99, 1489, + 1492, 1490, 1491, 2340, 3640, 2090, 1492, 1489, 8, 1490, + 1491, 3064, 3045, 1492, 1, 3083, 1042, 1457, 2738, 1764, + 1456, 1492, 3606, 3502, 1489, 3048, 1490, 1491, 4163, 701, + 2382, 1730, 1489, 2372, 1490, 1491, 2736, 1764, 4203, 3101, + 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 4159, + 1765, 2379, 2729, 1764, 4160, 1989, 1492, 2727, 1764, 3118, + 1489, 1979, 1490, 1491, 3668, 2308, 3951, 3020, 1492, 3084, + 3336, 2547, 3634, 3498, 2504, 1489, 1143, 1490, 1491, 2969, + 1489, 156, 1490, 1491, 2462, 2463, 4128, 120, 1101, 119, + 1492, 2404, 3434, 1489, 1146, 1490, 1491, 1254, 3433, 2542, + 3658, 2958, 2471, 1823, 1821, 3425, 1822, 3068, 1820, 1489, + 1492, 1490, 1491, 3423, 1489, 3085, 1490, 1491, 1825, 3122, + 1824, 3160, 3178, 3162, 3054, 4100, 3405, 3055, 2703, 3503, + 1489, 2082, 1490, 1491, 2998, 1489, 738, 1490, 1491, 3173, + 3174, 3175, 3176, 2930, 732, 194, 1812, 3065, 2859, 1489, + 1791, 1490, 1491, 2075, 1185, 1489, 3196, 1490, 1491, 691, + 2858, 3310, 1489, 2580, 1490, 1491, 3185, 697, 1542, 2070, + 1489, 3215, 1490, 1491, 2945, 3187, 1492, 1095, 1087, 2393, + 2440, 2879, 2854, 3111, 1492, 1094, 3928, 3249, 1492, 3561, + 3227, 3229, 2897, 2343, 3232, 2343, 3158, 3225, 2345, 4033, + 2345, 3757, 2853, 2518, 3248, 1489, 87, 1490, 1491, 2440, + 2440, 2440, 2440, 2440, 1492, 4113, 2955, 1489, 1787, 1490, + 1491, 3196, 3168, 3169, 3170, 3171, 3172, 3523, 2675, 2440, + 2189, 1532, 2440, 763, 3253, 2439, 3186, 934, 3188, 1489, + 1773, 1490, 1491, 3724, 2109, 3223, 3195, 761, 760, 1492, + 758, 3270, 2442, 2881, 2911, 1496, 1495, 969, 2869, 1489, + 3213, 1490, 1491, 3208, 3210, 3212, 3207, 1799, 2852, 2922, + 1492, 2920, 2919, 2617, 2031, 1492, 2851, 3222, 1053, 3220, + 2850, 2442, 2442, 2442, 2442, 2442, 1492, 2447, 3235, 3236, + 1492, 3587, 3583, 4155, 3272, 3353, 2441, 3273, 2437, 2888, + 920, 2442, 3252, 919, 2442, 3361, 2849, 3255, 3256, 3254, + 3258, 770, 3257, 3266, 1054, 762, 1055, 106, 1492, 107, + 752, 983, 1492, 3274, 918, 1489, 917, 1490, 1491, 3363, + 3221, 3364, 3280, 1489, 3028, 1490, 1491, 1489, 1492, 1490, + 1491, 2840, 1492, 3378, 3311, 3030, 3313, 2956, 3374, 3312, + 3238, 1473, 1492, 2923, 2926, 2927, 2928, 2924, 1749, 2925, + 2929, 1752, 2839, 1489, 2401, 1490, 1491, 2838, 1114, 3314, + 3315, 3402, 4059, 3365, 3362, 3334, 2506, 3355, 2837, 3366, + 2643, 3431, 2834, 1748, 4066, 3344, 3372, 3652, 3325, 3004, + 2534, 1492, 69, 46, 4028, 4097, 1492, 912, 1489, 909, + 1490, 1491, 3726, 1492, 3727, 3392, 3244, 3390, 3728, 3181, + 2829, 3244, 3182, 4079, 2822, 4080, 908, 3400, 3393, 1489, + 4081, 1490, 1491, 2246, 1489, 1467, 1490, 1491, 3410, 1464, + 2821, 4176, 2084, 98, 2820, 1489, 36, 1490, 1491, 1489, + 35, 1490, 1491, 34, 2819, 33, 32, 3426, 3427, 3428, + 3429, 3430, 26, 3407, 3408, 25, 3409, 24, 23, 3411, + 22, 3413, 29, 3415, 19, 21, 20, 1489, 18, 1490, + 1491, 1489, 3347, 1490, 1491, 4198, 4243, 125, 55, 52, + 1545, 50, 2662, 2818, 1545, 133, 2667, 1489, 2817, 1490, + 1491, 1489, 132, 1490, 1491, 2816, 3335, 53, 49, 1228, + 3548, 1489, 3550, 1490, 1491, 47, 96, 31, 30, 2670, + 17, 2671, 16, 3518, 15, 14, 13, 2679, 12, 11, + 3522, 2681, 2682, 7, 6, 39, 38, 37, 28, 27, + 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, + 1489, 2699, 1490, 1491, 40, 1489, 4, 1490, 1491, 2991, + 3247, 2536, 1489, 3401, 1490, 1491, 0, 0, 0, 0, + 0, 0, 2440, 0, 2705, 2706, 2707, 2708, 1726, 2710, + 2711, 3549, 2713, 3551, 0, 3600, 2715, 3558, 3553, 0, + 2720, 2721, 3565, 2722, 0, 0, 2725, 2726, 2728, 2730, + 2731, 2732, 2733, 2734, 2735, 2737, 2739, 2740, 2741, 2743, + 3356, 2745, 2746, 2748, 2750, 2752, 2754, 2756, 2758, 2760, + 2762, 2764, 2766, 2768, 2770, 2772, 2774, 2776, 2778, 2780, + 2782, 2783, 2784, 750, 2786, 3592, 2788, 3595, 2790, 2791, + 3589, 2793, 2795, 2797, 2442, 3570, 3525, 2800, 3527, 3528, + 3529, 2804, 0, 3365, 3362, 2809, 2810, 2811, 2812, 3366, + 1733, 3601, 3594, 3395, 3396, 0, 0, 1492, 2823, 2824, + 2825, 2826, 2827, 2828, 3555, 1492, 2832, 2833, 0, 3662, + 3663, 0, 0, 0, 2835, 3617, 0, 3619, 1492, 2841, + 0, 0, 1492, 0, 2844, 2845, 2846, 2847, 2848, 0, + 3611, 3612, 1492, 0, 0, 2855, 2856, 3582, 2857, 1492, + 0, 2860, 2862, 2404, 1492, 2864, 0, 0, 1492, 683, + 0, 0, 1492, 0, 0, 2876, 3596, 3597, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1492, 0, 1037, + 0, 3664, 0, 0, 1074, 2894, 1492, 1080, 1080, 0, + 1492, 0, 3645, 0, 1492, 0, 3649, 3650, 3651, 2815, + 0, 0, 0, 0, 0, 1492, 0, 2814, 2923, 2926, + 2927, 2928, 2924, 0, 2925, 2929, 0, 0, 3585, 3586, + 2808, 0, 0, 1109, 2807, 0, 0, 0, 0, 1492, + 3680, 0, 0, 0, 2806, 1492, 0, 0, 0, 3691, + 1492, 2803, 0, 0, 0, 0, 2802, 0, 1492, 0, + 2801, 0, 1492, 0, 2799, 0, 1489, 0, 1490, 1491, + 1492, 0, 0, 0, 1489, 0, 1490, 1491, 3713, 2792, + 1492, 3732, 0, 3733, 3734, 3735, 0, 1489, 2789, 1490, + 1491, 1489, 2787, 1490, 1491, 1492, 2785, 3742, 0, 0, + 3749, 1489, 3751, 1490, 1491, 0, 0, 2744, 1489, 0, + 1490, 1491, 0, 1489, 3722, 1490, 1491, 1489, 0, 1490, + 1491, 1489, 0, 1490, 1491, 3248, 0, 3752, 87, 0, + 3248, 2724, 3685, 0, 0, 0, 1489, 2723, 1490, 1491, + 0, 0, 2719, 0, 0, 1489, 2153, 1490, 1491, 1489, + 2717, 1490, 1491, 1489, 2709, 1490, 1491, 0, 0, 2151, + 0, 3782, 2680, 3753, 1489, 3772, 1490, 1491, 3762, 3761, + 0, 0, 2674, 0, 0, 0, 3774, 3769, 0, 3771, + 0, 0, 0, 0, 0, 3641, 3642, 2669, 1489, 0, + 1490, 1491, 0, 0, 1489, 3934, 1490, 1491, 0, 1489, + 42, 1490, 1491, 0, 0, 0, 3786, 1489, 0, 1490, + 1491, 1489, 0, 1490, 1491, 0, 0, 0, 0, 1489, + 0, 1490, 1491, 0, 0, 0, 0, 0, 0, 1489, + 0, 1490, 1491, 0, 0, 0, 0, 3926, 3925, 0, + 3953, 3941, 0, 0, 1489, 0, 1490, 1491, 3924, 0, + 0, 3946, 3945, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1754, 0, 0, 0, 0, 3096, 3097, + 3098, 3099, 3100, 3992, 2153, 3993, 3776, 1762, 0, 0, + 1755, 3750, 0, 0, 0, 0, 0, 2151, 3115, 3996, + 0, 0, 0, 0, 0, 0, 0, 0, 3783, 3784, + 0, 0, 3936, 3937, 3938, 2398, 2399, 1761, 1759, 1760, + 1756, 0, 1757, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4041, 3248, 3244, 3999, 3778, 0, 0, + 4002, 0, 0, 0, 0, 1758, 4032, 0, 1563, 1564, + 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, + 1575, 1576, 1577, 1578, 1579, 1580, 1581, 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, @@ -1788,1090 +2095,751 @@ var yyAct = [...]int{ 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, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, - 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, - 1676, 1677, 1440, 1522, 1271, 2550, 1678, 4036, 1680, 1681, - 1682, 1683, 1684, 1441, 1442, 2974, 3331, 3332, 3588, 3589, - 1551, 1551, 1551, 1551, 1551, 1551, 1535, 1121, 4150, 3335, - 1515, 975, 4082, 975, 724, 1691, 1692, 1693, 1694, 1695, - 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1518, - 1519, 1520, 1521, 1526, 2997, 715, 4121, 975, 1515, 1532, - 3657, 4121, 1467, 3700, 3700, 1083, 1718, 165, 3331, 3332, - 716, 1224, 4149, 1547, 177, 1548, 1549, 1234, 1459, 94, - 2624, 3335, 1977, 1976, 1978, 1979, 1980, 1717, 4120, 1221, - 94, 94, 165, 4120, 1552, 1553, 3541, 1216, 2996, 177, - 2977, 1897, 1083, 2993, 1233, 1142, 1239, 1240, 1241, 1242, - 2008, 1865, 89, 1172, 2623, 185, 3044, 3485, 1228, 1135, - 1724, 674, 3385, 1171, 1753, 4160, 2548, 2854, 2856, 1042, - 1279, 1280, 3021, 1042, 4024, 3020, 1467, 1516, 1517, 1042, - 185, 4231, 3579, 3561, 2640, 2924, 2889, 2826, 2143, 1782, - 3031, 719, 1679, 1179, 1227, 1142, 1715, 3172, 166, 171, - 168, 174, 175, 176, 178, 180, 181, 182, 183, 1716, - 1477, 1247, 2884, 2494, 184, 186, 187, 188, 1142, 682, - 2444, 1515, 124, 166, 171, 168, 174, 175, 176, 178, - 180, 181, 182, 183, 2402, 3257, 1512, 1142, 2184, 184, - 186, 187, 188, 2651, 1260, 1495, 3265, 1058, 1141, 1274, - 1896, 2176, 4050, 1165, 2495, 2185, 119, 3620, 3553, 1754, - 1732, 2493, 94, 1232, 1736, 2023, 2568, 1734, 1735, 2077, - 1041, 104, 105, 2004, 1796, 3071, 2510, 1716, 1685, 1686, - 1687, 1688, 1689, 1690, 1477, 1995, 4196, 3749, 1722, 1507, - 1508, 1510, 1509, 1511, 1512, 2496, 1482, 3266, 1141, 1115, - 1211, 3595, 4188, 1145, 1135, 2492, 1481, 1482, 1147, 3594, - 2535, 107, 1148, 1146, 1906, 1483, 1142, 2176, 1905, 2660, - 1895, 1141, 3268, 1473, 2540, 3034, 1465, 1135, 1138, 1139, - 3033, 1099, 2540, 1149, 120, 1132, 1136, 1873, 1874, 1875, - 1141, 2855, 3263, 2651, 1730, 1142, 1135, 1138, 1139, 2545, - 1099, 1889, 2543, 1153, 1132, 1136, 1131, 1151, 1053, 1756, - 3580, 3034, 3279, 3280, 1215, 1733, 3033, 2544, 1719, 3264, - 1960, 4233, 1882, 2547, 2016, 2542, 1038, 4083, 1759, 4016, - 1040, 1911, 1731, 1912, 1985, 1914, 1916, 3921, 1901, 1920, - 1922, 1924, 1926, 1928, 2182, 1942, 3920, 1473, 3051, 2332, - 1282, 1983, 1261, 3270, 1950, 1951, 720, 1787, 1788, 2167, - 1956, 1957, 1900, 4229, 1856, 1217, 4230, 1231, 4228, 1141, - 2111, 1178, 3654, 2024, 3655, 1175, 4084, 1246, 4017, 1864, - 2400, 2401, 1899, 1899, 2112, 1513, 1514, 2110, 1248, 4239, - 1992, 3911, 1993, 1879, 3671, 1994, 3670, 1880, 1141, 1892, - 3602, 1878, 2332, 1145, 1135, 1984, 2329, 1972, 1147, 1737, - 3601, 1754, 1148, 1146, 1480, 2331, 1481, 1482, 725, 2181, - 1903, 3278, 1982, 3073, 1214, 3591, 1946, 2099, 2100, 2097, - 2098, 973, 3053, 3281, 977, 978, 979, 1483, 3308, 3297, - 1114, 2949, 1483, 2099, 2100, 2630, 2631, 1938, 2012, 1483, - 1941, 2948, 1943, 2947, 2096, 2500, 2697, 1986, 2159, 2148, - 2149, 2150, 2151, 2161, 2152, 2153, 2154, 2166, 2162, 2155, - 2156, 2163, 2164, 2165, 2157, 2158, 2160, 1483, 1971, 1970, - 190, 1969, 128, 1483, 1968, 4240, 1118, 1117, 1116, 1483, - 1958, 2978, 1505, 1506, 1507, 1508, 1510, 1509, 1511, 1512, - 1790, 2029, 1952, 129, 1949, 151, 3063, 3062, 3061, 2407, - 2408, 3055, 1948, 3059, 1947, 3054, 1918, 3052, 1729, 172, - 1282, 1282, 3057, 1483, 3360, 1446, 2025, 2026, 1483, 4201, - 1754, 3056, 2875, 4216, 2051, 1754, 87, 4189, 4045, 87, - 2030, 4199, 1754, 3552, 3585, 3402, 725, 2037, 2038, 2039, - 3058, 3060, 4044, 162, 3267, 4020, 2931, 2050, 725, 150, - 1489, 1490, 1491, 1492, 1493, 1494, 1488, 1485, 4019, 1472, - 1469, 1470, 1471, 1476, 1478, 1475, 2516, 1474, 2515, 169, - 4018, 3943, 170, 1754, 1767, 2699, 1480, 1468, 1481, 1482, - 2514, 1480, 2513, 1481, 1482, 1479, 1754, 2942, 1480, 101, - 1481, 1482, 4176, 1754, 1885, 1886, 161, 160, 189, 102, - 3916, 1483, 2138, 2138, 2136, 2136, 1754, 2139, 2875, 1754, - 4129, 1754, 1483, 2512, 3900, 2511, 1480, 42, 1481, 1482, - 42, 3899, 1480, 1768, 1481, 1482, 3748, 2101, 1480, 1717, - 1481, 1482, 1483, 1472, 1469, 1470, 1471, 1476, 1478, 1475, - 3746, 1474, 4038, 2027, 1479, 1754, 2875, 4114, 2875, 4093, - 2031, 1468, 2033, 2034, 2035, 2036, 2687, 3667, 1501, 2040, - 1754, 1497, 1480, 1498, 1481, 1482, 1714, 1480, 1713, 1481, - 1482, 2052, 2222, 1483, 2875, 4089, 2236, 1499, 1513, 1514, - 1496, 1712, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1510, - 1509, 1511, 1512, 4127, 1754, 1483, 85, 3599, 1715, 85, - 155, 1887, 158, 2078, 1884, 1754, 156, 157, 4001, 1754, - 3948, 1716, 3584, 173, 2108, 3370, 1483, 2058, 2059, 2171, - 3638, 4035, 179, 1503, 1504, 1505, 1506, 1507, 1508, 1510, - 1509, 1511, 1512, 2114, 1483, 2116, 2117, 2118, 2119, 2120, - 2121, 2123, 2125, 2126, 2127, 2128, 2129, 2130, 1483, 2113, - 1480, 3367, 1481, 1482, 3300, 2649, 2319, 2320, 2321, 2322, - 2323, 1480, 2656, 1481, 1482, 2648, 2342, 110, 2142, 2115, - 2341, 3924, 1754, 2344, 2246, 2340, 2347, 2348, 109, 101, - 108, 1480, 3299, 1481, 1482, 103, 3271, 4125, 1754, 102, - 3275, 3025, 1526, 2186, 2187, 2188, 2189, 3274, 2875, 3912, - 3947, 2328, 2330, 3638, 1754, 2875, 3636, 2200, 3994, 1754, - 2177, 2365, 2221, 2540, 1754, 3559, 1754, 2781, 1754, 3904, - 2238, 1483, 1480, 2958, 1481, 1482, 3992, 1754, 3290, 3289, - 3903, 3276, 2945, 2920, 1483, 1711, 3272, 3287, 3288, 103, - 2655, 3273, 3285, 3286, 1480, 2647, 1481, 1482, 3285, 3284, - 1754, 164, 1483, 1754, 2899, 1754, 2623, 3006, 2423, 2339, - 1705, 1711, 2345, 2346, 1483, 1480, 1709, 1481, 1482, 2342, - 2613, 1707, 1483, 2412, 1708, 1706, 2605, 1710, 2340, 1860, - 2987, 104, 105, 1480, 2604, 1481, 1482, 2980, 2981, 3646, - 1501, 2562, 3043, 1771, 2561, 1483, 2453, 1480, 2397, 1481, - 1482, 2921, 104, 105, 1754, 2375, 1483, 2376, 1501, 2387, - 2054, 2923, 2020, 2107, 1502, 1503, 1504, 1505, 1506, 1507, - 1508, 1510, 1509, 1511, 1512, 1981, 3989, 1754, 2875, 2874, - 2701, 1104, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1510, - 1509, 1511, 1512, 1973, 3971, 1754, 2984, 159, 1963, 2425, - 2963, 2462, 2463, 2464, 2465, 2457, 3574, 2458, 2459, 2460, - 2461, 2447, 1054, 2448, 1770, 1104, 2891, 2872, 1959, 2363, - 1480, 2467, 1481, 1482, 2469, 2470, 2471, 2472, 2429, 2388, - 2381, 103, 2382, 1480, 1955, 1481, 1482, 3526, 1754, 2452, - 2390, 1954, 2483, 2141, 1754, 95, 1953, 1769, 3521, 2451, - 109, 1480, 1272, 1481, 1482, 3556, 1501, 2529, 2639, 2410, - 1483, 2489, 2891, 1480, 1483, 1481, 1482, 1479, 2434, 2435, - 2433, 1480, 1088, 1481, 1482, 1089, 2450, 2920, 2449, 2541, - 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1510, 1509, 1511, - 1512, 1860, 1859, 2899, 1480, 2870, 1481, 1482, 4077, 2526, - 1802, 1801, 2499, 2898, 4049, 1480, 152, 1481, 1482, 153, - 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1510, 1509, 1511, - 1512, 3222, 2484, 3555, 1479, 2480, 2473, 2475, 2476, 2875, - 2899, 2498, 3552, 2534, 1483, 2503, 2537, 2502, 2538, 3552, - 165, 3252, 3505, 2540, 3287, 2921, 3195, 177, 3603, 2436, - 2781, 2623, 2554, 4190, 2684, 2623, 3519, 1754, 2484, 2533, - 2536, 2532, 1143, 2683, 2899, 1501, 2540, 1483, 2523, 2405, - 1758, 1144, 1483, 2366, 2141, 2079, 2063, 2555, 1483, 2558, - 2006, 1899, 1483, 2559, 2560, 1789, 1483, 1126, 185, 1502, - 1503, 1504, 1505, 1506, 1507, 1508, 1510, 1509, 1511, 1512, - 1483, 1755, 1757, 1125, 1483, 3604, 3605, 3606, 1483, 1480, - 4155, 1481, 1482, 1480, 2628, 1481, 1482, 4096, 3935, 1043, - 1761, 3901, 3311, 1042, 1042, 1042, 3516, 1754, 2565, 3761, - 3619, 166, 171, 168, 174, 175, 176, 178, 180, 181, - 182, 183, 110, 1536, 3616, 1536, 3597, 184, 186, 187, - 188, 3418, 1483, 109, 3417, 108, 1862, 2482, 3572, 3514, - 1754, 2643, 3358, 103, 3477, 1754, 3313, 3309, 2988, 1483, - 3475, 1754, 2598, 1483, 3471, 1754, 2479, 2955, 3468, 1754, - 2342, 1501, 1483, 1480, 2341, 1481, 1482, 1483, 2474, 2646, - 2468, 1483, 3466, 1754, 2466, 1483, 3464, 1754, 1988, 1483, - 3462, 1754, 95, 1894, 1483, 1502, 1503, 1504, 1505, 1506, - 1507, 1508, 1510, 1509, 1511, 1512, 1480, 1890, 1481, 1482, - 1483, 1480, 1858, 1481, 1482, 2615, 2666, 1480, 1754, 1481, - 1482, 1480, 121, 1481, 1482, 1480, 1216, 1481, 1482, 2954, - 2621, 3566, 3567, 2681, 3460, 1754, 3362, 3936, 1483, 1480, - 2497, 1481, 1482, 1480, 2629, 1481, 1482, 1480, 1934, 1481, - 1482, 3458, 1754, 2379, 4211, 3456, 1754, 2635, 2056, 4209, - 2632, 2633, 2634, 1483, 3454, 1754, 4053, 1483, 2108, 3452, - 1754, 1483, 4183, 3450, 1754, 679, 4057, 3448, 1754, 3976, - 1483, 3446, 1754, 2955, 1483, 3569, 2636, 4033, 2638, 3305, - 3304, 1480, 1483, 1481, 1482, 3303, 3222, 2641, 2967, 2642, - 1483, 2599, 3444, 1754, 1483, 1935, 1936, 1937, 1480, 1766, - 1481, 1482, 1480, 3244, 1481, 1482, 3571, 1483, 3245, 2659, - 3241, 1480, 2637, 1481, 1482, 2057, 1480, 3240, 1481, 1482, - 1480, 3908, 1481, 1482, 1480, 1056, 1481, 1482, 1480, 3242, - 1481, 1482, 3937, 1480, 3243, 1481, 1482, 1483, 2644, 742, - 2396, 2825, 2385, 1483, 3560, 3442, 1754, 3200, 3199, 1480, - 3621, 1481, 1482, 3440, 1754, 2607, 2608, 4015, 1483, 3739, - 2610, 3548, 3438, 1754, 3545, 2695, 3517, 2167, 1483, 2611, - 3741, 2813, 3544, 2857, 3424, 1754, 1057, 1480, 3209, 1481, - 1482, 2005, 3400, 1754, 1026, 3283, 2846, 1754, 3246, 2938, - 2908, 2909, 1042, 2138, 3726, 2136, 3725, 2860, 1483, 2844, - 1754, 2959, 1480, 2184, 1481, 1482, 1480, 2591, 1481, 1482, - 1480, 1483, 1481, 1482, 2590, 2896, 2897, 1182, 2858, 1480, - 2185, 1481, 1482, 1480, 2423, 1481, 1482, 1042, 2916, 2819, - 1754, 1480, 2589, 1481, 1482, 2796, 1754, 2588, 2861, 1480, - 2863, 1481, 1482, 1480, 2587, 1481, 1482, 1059, 1483, 3724, - 2788, 1754, 1483, 2895, 2586, 1060, 1480, 2107, 1481, 1482, - 2779, 1754, 1483, 2876, 2585, 1181, 2159, 2148, 2149, 2150, - 2151, 2161, 2152, 2153, 2154, 2166, 2162, 2155, 2156, 2163, - 2164, 2165, 2157, 2158, 2160, 3378, 1480, 2954, 1481, 1482, - 2777, 1754, 1480, 3037, 1481, 1482, 1483, 1722, 2848, 1445, - 2885, 2914, 1068, 2764, 1754, 2994, 42, 1480, 129, 1481, - 1482, 101, 3550, 1483, 103, 2913, 1067, 1480, 2915, 1481, - 1482, 102, 2868, 4225, 2941, 2943, 2971, 1483, 1716, 3212, - 3214, 1483, 2104, 2102, 2103, 2888, 2934, 1483, 3215, 2873, - 2762, 1754, 2992, 1483, 2760, 1754, 101, 1480, 2918, 1481, - 1482, 2602, 103, 4132, 2758, 1754, 102, 4034, 3931, 2922, - 1480, 3528, 1481, 1482, 2925, 1483, 110, 2407, 2408, 2489, - 2932, 3282, 2912, 2391, 1483, 2935, 2627, 109, 2957, 108, - 3003, 2179, 3198, 2960, 2961, 2062, 2180, 103, 2756, 1754, - 3197, 2061, 2946, 108, 4000, 3999, 3607, 1480, 1483, 1481, - 1482, 1480, 3979, 1481, 1482, 2754, 1754, 1483, 3747, 2956, - 3745, 1480, 3744, 1481, 1482, 1483, 3737, 3736, 3617, 2752, - 1754, 3549, 2964, 3483, 2242, 2968, 2969, 2970, 2965, 2750, - 1754, 110, 1483, 3547, 3000, 2748, 1754, 1483, 3314, 1882, - 2524, 1483, 109, 1930, 108, 1480, 1877, 1481, 1482, 3608, - 3609, 3610, 110, 2989, 2990, 1066, 109, 2746, 1754, 3538, - 4212, 2891, 1480, 109, 1481, 1482, 2744, 1754, 3710, 2999, - 3047, 3048, 4213, 4212, 4213, 3067, 1480, 2872, 1481, 1482, - 1480, 1483, 1481, 1482, 3101, 1483, 1480, 2685, 1481, 1482, - 2742, 1754, 1480, 1483, 1481, 1482, 1931, 1932, 1933, 2740, - 1754, 2377, 1483, 3026, 2325, 1783, 3064, 2738, 1754, 1483, - 3045, 1775, 114, 115, 1480, 4021, 1481, 1482, 3029, 1483, - 3583, 3, 97, 1480, 3479, 1481, 1482, 1, 2076, 2736, - 1754, 10, 1034, 3415, 2357, 3082, 3083, 3084, 3085, 3086, - 3087, 3088, 3089, 3090, 3091, 2074, 1448, 1480, 9, 1481, - 1482, 1755, 2364, 3001, 2075, 3099, 1480, 8, 1481, 1482, - 1447, 3587, 3065, 4144, 1480, 695, 1481, 1482, 2367, 1720, - 4184, 4140, 4141, 2734, 1754, 1974, 1964, 2732, 1754, 3649, - 2293, 1480, 1483, 1481, 1482, 3414, 1480, 3932, 1481, 1482, - 1480, 2389, 1481, 1482, 2730, 1754, 1483, 3317, 2530, 3615, - 1483, 2725, 1754, 2487, 1483, 1134, 154, 3141, 3049, 3143, - 2445, 3406, 3103, 2446, 1483, 3159, 3066, 3035, 4109, 118, - 3036, 1092, 117, 1137, 1483, 3154, 3155, 3156, 3157, 1245, - 1480, 2979, 1481, 1482, 1480, 2525, 1481, 1482, 1483, 3639, - 3046, 2939, 1480, 2454, 1481, 1482, 1808, 1806, 1807, 1805, - 1810, 1480, 3177, 1481, 1482, 1809, 4081, 3386, 1480, 2686, - 1481, 1482, 3166, 3168, 3484, 2067, 732, 2911, 1480, 726, - 1481, 1482, 192, 2423, 2721, 1754, 3092, 2328, 2330, 2328, - 2330, 1483, 1797, 1776, 2060, 1176, 685, 3291, 2719, 1754, - 2563, 691, 3404, 3139, 1533, 3229, 2842, 87, 2501, 2055, - 2423, 2423, 2423, 2423, 2423, 3196, 2841, 3149, 3150, 3151, - 3152, 3153, 2926, 1086, 1078, 3177, 2712, 1754, 2378, 2862, - 2423, 1085, 3909, 2423, 3230, 3542, 3167, 3208, 3169, 3210, - 2837, 1480, 1483, 1481, 1482, 2878, 3176, 1483, 3234, 3213, - 3206, 2016, 3251, 4014, 3738, 1480, 4094, 1481, 1482, 1480, - 3204, 1481, 1482, 1480, 2936, 1481, 1482, 1483, 3194, 3188, - 1772, 1483, 3504, 1480, 2425, 1481, 1482, 1483, 2658, 2174, - 3203, 1523, 3201, 1480, 2950, 1481, 1482, 757, 2422, 3216, - 3217, 3705, 2094, 755, 754, 752, 3334, 1480, 1045, 1481, - 1482, 2425, 2425, 2425, 2425, 2425, 3342, 3253, 3233, 1483, - 3254, 1046, 3202, 3236, 3237, 3235, 3239, 1483, 3238, 104, - 105, 2425, 3247, 1047, 2425, 1483, 2864, 3255, 3189, 3191, - 3193, 2892, 1487, 3261, 2710, 1754, 1486, 963, 2852, 2836, - 1480, 1784, 1481, 1482, 1483, 2903, 3292, 2901, 3294, 2900, - 2600, 2430, 3295, 3296, 3568, 3293, 1483, 3564, 4136, 2835, - 2424, 2420, 2871, 2834, 914, 3346, 913, 764, 756, 2833, - 746, 976, 912, 3343, 911, 3344, 3345, 3219, 3009, 2489, - 3336, 3315, 3359, 3011, 2937, 3347, 3355, 1464, 3353, 1739, - 1742, 1480, 2386, 1481, 1482, 1105, 1480, 3383, 1481, 1482, - 3225, 2832, 4040, 2626, 3412, 3225, 1483, 1738, 4047, 2823, - 3325, 3371, 3374, 3373, 3633, 3306, 1480, 2822, 1481, 1482, - 1480, 2985, 1481, 1482, 3381, 2517, 1480, 69, 1481, 1482, - 46, 4009, 3391, 4078, 906, 903, 2821, 3388, 3389, 3707, - 3390, 3708, 3709, 3392, 3162, 3394, 3163, 3396, 2820, 4060, - 4061, 3407, 3408, 3409, 3410, 3411, 902, 4062, 1480, 2231, - 1481, 1482, 1458, 1455, 4157, 2069, 1480, 96, 1481, 1482, - 36, 35, 34, 33, 1480, 32, 1481, 1482, 26, 25, - 24, 1536, 23, 22, 29, 1536, 19, 2645, 21, 20, - 3316, 2650, 18, 1480, 3328, 1481, 1482, 4179, 2817, 4224, - 123, 3529, 55, 3531, 52, 1480, 50, 1481, 1482, 131, - 130, 53, 49, 1219, 2653, 47, 2654, 3499, 31, 30, - 17, 16, 2662, 15, 3503, 14, 2664, 2665, 13, 12, - 11, 7, 6, 39, 38, 2671, 2672, 2673, 2674, 2675, - 2676, 2677, 2678, 2679, 2680, 37, 2682, 28, 27, 40, - 4, 3228, 2972, 2519, 3382, 1480, 0, 1481, 1482, 0, - 0, 0, 1717, 2423, 0, 0, 3534, 1483, 0, 2688, - 2689, 2690, 2691, 744, 2693, 2694, 3581, 2696, 3530, 3539, - 3532, 2698, 3546, 0, 0, 2703, 2704, 0, 2705, 3551, - 0, 2708, 2709, 2711, 2713, 2714, 2715, 2716, 2717, 2718, - 2720, 2722, 2723, 2724, 2726, 3337, 2728, 2729, 2731, 2733, - 2735, 2737, 2739, 2741, 2743, 2745, 2747, 2749, 2751, 2753, - 2755, 2757, 2759, 2761, 2763, 2765, 2766, 2767, 3573, 2769, - 3575, 2771, 3570, 2773, 2774, 3346, 2776, 2778, 2780, 0, - 3576, 0, 2783, 3343, 3536, 3506, 2787, 3508, 3509, 3510, - 2792, 2793, 2794, 2795, 2425, 3347, 3582, 1483, 0, 2812, - 3598, 0, 3600, 2806, 2807, 2808, 2809, 2810, 2811, 1483, - 0, 2815, 2816, 3592, 3593, 3376, 3377, 3563, 1483, 2818, - 0, 0, 1065, 1483, 2824, 1071, 1071, 0, 1483, 2827, - 2828, 2829, 2830, 2831, 0, 0, 3577, 3578, 0, 0, - 2838, 2839, 0, 2840, 0, 1483, 2843, 2845, 2389, 1483, - 2847, 0, 0, 3643, 3644, 0, 1480, 0, 1481, 1482, - 2859, 1483, 0, 0, 0, 3626, 0, 1483, 0, 3630, - 3631, 3632, 1483, 0, 3645, 0, 1483, 0, 0, 0, - 0, 1483, 0, 0, 2904, 2907, 2908, 2909, 2905, 2805, - 2906, 2910, 0, 0, 3566, 3567, 0, 0, 0, 0, - 1483, 2804, 0, 0, 0, 3661, 0, 1483, 0, 0, - 2803, 1483, 0, 0, 0, 2802, 0, 0, 0, 0, - 2801, 0, 0, 1483, 0, 0, 0, 0, 1483, 0, - 0, 0, 0, 3672, 0, 0, 0, 2800, 0, 1483, - 0, 2799, 0, 1483, 0, 0, 1480, 0, 1481, 1482, - 0, 0, 3694, 2798, 0, 0, 0, 0, 1480, 2797, - 1481, 1482, 1483, 0, 2791, 0, 0, 1480, 2790, 1481, - 1482, 0, 1480, 2789, 1481, 1482, 1483, 1480, 3723, 1481, - 1482, 3730, 0, 3732, 0, 3713, 0, 3714, 3715, 3716, - 1483, 0, 2786, 3703, 1480, 1483, 1481, 1482, 1480, 2785, - 1481, 1482, 0, 2784, 0, 0, 3229, 0, 3733, 87, - 1480, 3229, 1481, 1482, 0, 2782, 1480, 0, 1481, 1482, - 2775, 1480, 0, 1481, 1482, 1480, 1483, 1481, 1482, 0, - 1480, 2772, 1481, 1482, 0, 2770, 0, 1483, 0, 3666, - 2138, 1483, 2136, 0, 3763, 3734, 3743, 3755, 3742, 1480, - 3753, 1481, 1482, 0, 2768, 3750, 1480, 3752, 1481, 1482, - 1480, 0, 1481, 1482, 1483, 0, 0, 0, 2727, 0, - 3622, 3623, 1480, 0, 1481, 1482, 3915, 1480, 0, 1481, - 1482, 0, 2707, 3767, 0, 0, 0, 2706, 1480, 0, - 1481, 1482, 1480, 0, 1481, 1482, 0, 0, 0, 0, - 42, 2904, 2907, 2908, 2909, 2905, 0, 2906, 2910, 0, - 0, 1480, 0, 1481, 1482, 0, 3907, 3906, 2702, 0, - 0, 0, 0, 0, 3934, 1480, 3922, 1481, 1482, 2700, - 0, 3905, 0, 2692, 3926, 3927, 0, 0, 0, 1480, - 0, 1481, 1482, 0, 1480, 0, 1481, 1482, 0, 3973, - 3974, 3077, 3078, 3079, 3080, 3081, 2663, 3757, 3764, 3765, - 0, 0, 3731, 0, 0, 3917, 3918, 3919, 2138, 0, - 2136, 3096, 3977, 0, 0, 1480, 0, 1481, 1482, 0, - 0, 0, 0, 0, 0, 0, 1480, 0, 1481, 1482, - 1480, 0, 1481, 1482, 0, 0, 0, 0, 0, 3225, - 0, 0, 3980, 0, 4022, 3229, 3983, 0, 3759, 0, - 4013, 0, 0, 1480, 0, 1481, 1482, 0, 0, 1554, - 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, - 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 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, 1653, 1654, 1655, 1656, - 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, - 1667, 1668, 1674, 1675, 1676, 1677, 1691, 1692, 1693, 1694, - 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, - 3978, 4023, 3228, 4007, 3997, 4006, 1483, 3228, 1744, 0, - 0, 4003, 0, 4005, 4041, 0, 0, 0, 0, 0, - 0, 0, 1752, 0, 0, 1745, 3910, 0, 0, 0, - 0, 3231, 87, 0, 0, 0, 4026, 0, 1717, 1483, - 0, 0, 0, 4025, 0, 0, 1744, 0, 0, 3249, - 2383, 2384, 1751, 1749, 1750, 1746, 0, 1747, 0, 4030, - 1752, 4043, 0, 1745, 0, 0, 0, 4046, 0, 0, - 4048, 0, 3914, 0, 0, 0, 0, 0, 0, 0, - 1748, 0, 0, 0, 0, 0, 0, 0, 1740, 1741, - 1751, 1749, 1750, 1746, 4055, 1747, 0, 0, 2657, 0, - 0, 0, 4065, 0, 0, 0, 0, 0, 0, 1484, - 0, 0, 0, 0, 0, 0, 0, 0, 1748, 0, - 0, 0, 0, 42, 0, 0, 4066, 0, 0, 4067, - 4091, 2652, 0, 0, 0, 87, 0, 0, 0, 0, - 1542, 0, 0, 0, 0, 0, 0, 0, 4076, 0, - 0, 0, 0, 0, 0, 1480, 0, 1481, 1482, 0, - 0, 4085, 0, 0, 1717, 0, 0, 0, 4027, 4097, - 0, 0, 0, 4095, 0, 3934, 4111, 3380, 4100, 4108, - 4105, 4102, 4101, 4099, 4104, 4103, 0, 0, 1480, 0, - 1481, 1482, 0, 0, 0, 0, 0, 0, 0, 3397, - 3398, 3228, 3399, 3401, 3403, 4130, 0, 0, 4153, 0, - 0, 0, 0, 4143, 0, 4135, 0, 4122, 4148, 0, - 0, 0, 0, 0, 4161, 0, 42, 0, 4163, 0, - 3416, 0, 0, 4174, 0, 3419, 0, 3421, 3422, 3423, - 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3433, 3434, - 3435, 3436, 3437, 3439, 3441, 3443, 3445, 3447, 3449, 3451, - 3453, 3455, 3457, 3459, 3461, 3463, 3465, 3467, 3469, 3470, - 3472, 3473, 3474, 3476, 4122, 4194, 3478, 2016, 3480, 3481, - 3482, 4193, 4204, 3486, 3487, 3488, 3489, 3490, 3491, 3492, - 3493, 3494, 3495, 3496, 4210, 2138, 4208, 2136, 4197, 4207, - 4206, 4203, 3502, 4178, 4173, 4218, 3507, 4092, 4032, 4087, - 3511, 3512, 0, 3513, 3515, 4226, 3518, 3520, 3225, 3522, - 3523, 3524, 3525, 4234, 4232, 0, 0, 0, 0, 3533, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4051, 4243, 4244, 3974, 4242, 0, 0, 0, - 0, 4122, 0, 2138, 0, 2136, 0, 4241, 0, 0, - 4039, 0, 0, 0, 3557, 3558, 0, 0, 3562, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4169, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4086, - 1774, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 86, 44, 45, 88, 0, 0, 1863, 0, - 0, 0, 0, 3637, 0, 0, 0, 0, 0, 0, - 0, 92, 0, 0, 0, 48, 76, 77, 0, 74, - 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 75, 0, 0, 0, 0, 0, 1723, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3656, 0, - 0, 3660, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 1024, 0, 0, - 2332, 0, 0, 1025, 0, 3673, 0, 0, 0, 0, - 0, 0, 4191, 2137, 0, 0, 677, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1029, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 2021, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3696, - 0, 0, 0, 0, 0, 0, 0, 0, 1100, 0, - 0, 0, 3704, 0, 0, 0, 0, 0, 0, 3711, - 0, 0, 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, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, - 1020, 1021, 1022, 1023, 0, 0, 0, 0, 0, 0, - 51, 54, 57, 56, 59, 0, 73, 0, 0, 82, - 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 61, 91, 90, 0, 0, 71, 72, - 58, 0, 0, 0, 0, 0, 80, 81, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3923, 0, - 0, 0, 0, 0, 0, 0, 0, 3930, 0, 0, - 63, 64, 0, 65, 66, 67, 68, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3940, 3941, 3942, - 0, 3944, 0, 3945, 3946, 0, 0, 0, 0, 3949, - 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, - 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, - 3970, 0, 3972, 3975, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2089, 2090, 2091, 2092, 60, 3984, 3985, - 3986, 3987, 3988, 3990, 3991, 3993, 3995, 3996, 3998, 2105, - 0, 0, 4002, 0, 0, 0, 4004, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2144, 2145, 0, 0, 0, 0, - 2168, 4031, 0, 2172, 2173, 0, 0, 0, 2178, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2190, 2191, 2192, 2193, 2194, 2195, 2196, - 2197, 2198, 2199, 0, 2201, 0, 0, 89, 2223, 2224, - 2225, 2226, 2227, 2228, 2229, 2230, 2232, 0, 2237, 0, - 2239, 2240, 2241, 0, 2243, 2244, 2245, 0, 2247, 2248, - 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, - 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, - 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, - 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, - 2289, 2290, 2291, 2292, 2296, 2297, 2298, 2299, 2300, 2301, - 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, - 2312, 2313, 2314, 2315, 2316, 2317, 2318, 0, 0, 0, - 0, 0, 2324, 0, 2326, 0, 2333, 2334, 2335, 2336, - 2337, 2338, 0, 0, 0, 0, 0, 94, 0, 0, - 0, 0, 0, 0, 0, 2349, 2350, 2351, 2352, 2353, - 2354, 2355, 2356, 0, 2358, 2359, 2360, 2361, 2362, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 190, 0, 0, 1071, 4177, 0, 0, 0, 4056, 0, - 0, 0, 0, 1826, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 129, 0, 151, 0, 0, 0, 0, - 0, 0, 4071, 0, 2403, 2404, 0, 0, 4074, 172, - 4075, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 70, 0, 0, 0, 0, 0, - 2442, 0, 0, 4090, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 162, 0, 190, 0, 0, 1826, 150, - 0, 0, 1220, 0, 1226, 0, 1881, 0, 0, 4116, - 4117, 0, 0, 0, 959, 0, 0, 0, 129, 169, - 151, 0, 170, 4124, 4126, 4128, 0, 0, 0, 0, - 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, - 0, 4134, 2485, 0, 138, 139, 161, 160, 189, 0, - 0, 0, 0, 4156, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1454, 0, 162, 0, - 195, 0, 0, 195, 150, 0, 0, 730, 0, 0, - 0, 0, 736, 0, 0, 0, 0, 0, 0, 0, - 1813, 4175, 0, 195, 169, 0, 0, 170, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1885, - 1886, 161, 160, 189, 0, 4198, 4200, 4202, 0, 0, - 0, 0, 0, 0, 736, 195, 736, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 155, 136, 158, 143, 135, 1813, 156, 157, 4223, 0, - 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, - 0, 0, 179, 144, 1827, 0, 4235, 4236, 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, 0, 0, 0, 148, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 155, 1887, 158, 0, 1884, - 0, 156, 157, 0, 0, 0, 0, 0, 173, 1827, - 1840, 1843, 1844, 1845, 1846, 1847, 1848, 179, 1849, 1850, - 1852, 1853, 1851, 1854, 1855, 1828, 1829, 1830, 1831, 1811, - 1812, 1841, 0, 1814, 0, 1815, 1816, 1817, 1818, 1819, - 1820, 1821, 1822, 1823, 0, 0, 1824, 1832, 1833, 1834, - 1835, 0, 1836, 1837, 1838, 1839, 0, 0, 1825, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 164, 0, 0, 0, 1840, 1843, 1844, 1845, 1846, - 1847, 1848, 0, 1849, 1850, 1852, 1853, 1851, 1854, 1855, - 1828, 1829, 1830, 1831, 1811, 1812, 1841, 0, 1814, 0, - 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 0, - 0, 1824, 1832, 1833, 1834, 1835, 0, 1836, 1837, 1838, - 1839, 0, 0, 1825, 0, 0, 0, 0, 0, 0, - 2661, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2667, 2668, 2669, 2670, 0, 0, 164, 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, 1786, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1542, 0, 0, 0, 0, - 0, 1803, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 1842, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1944, 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, 1989, - 165, 0, 0, 0, 0, 0, 0, 177, 0, 0, - 0, 0, 0, 0, 0, 0, 2017, 0, 1842, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2028, 0, 0, 0, 0, 0, 0, 2032, - 0, 152, 0, 0, 153, 0, 0, 0, 185, 1774, - 2043, 2044, 2045, 2046, 2047, 2048, 2049, 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, 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, 185, 0, 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, 195, 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, 736, 0, - 736, 736, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 736, 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, - 0, 1528, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2082, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3042, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3068, - 3069, 3070, 0, 0, 3072, 0, 0, 3074, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3093, 3094, 3095, - 0, 0, 0, 0, 0, 0, 3100, 0, 0, 0, - 0, 3102, 0, 0, 3104, 3105, 3106, 0, 0, 0, - 3107, 3108, 0, 0, 3109, 0, 3110, 0, 0, 0, - 0, 0, 0, 3111, 0, 3112, 0, 0, 0, 3113, - 0, 3114, 0, 0, 3115, 0, 3116, 0, 3117, 0, - 3118, 0, 3119, 0, 3120, 0, 3121, 0, 3122, 0, - 3123, 0, 3124, 0, 3125, 0, 3126, 0, 3127, 0, - 3128, 0, 3129, 0, 3130, 0, 3131, 0, 3132, 0, - 0, 0, 3133, 0, 3134, 0, 3135, 0, 0, 3136, - 0, 3137, 0, 3138, 0, 2296, 3140, 0, 0, 3142, - 0, 0, 3144, 3145, 3146, 3147, 0, 0, 0, 0, - 3148, 2296, 2296, 2296, 2296, 2296, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3158, 0, 0, 0, - 0, 0, 0, 0, 3171, 0, 0, 3175, 0, 0, - 0, 0, 0, 0, 0, 0, 3178, 3179, 3180, 3181, - 3182, 3183, 0, 0, 0, 3184, 3185, 0, 3186, 0, - 3187, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 0, 0, 0, 736, 736, 0, 0, - 0, 0, 0, 0, 1071, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3220, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 736, 0, 0, 195, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3250, 736, 0, 2409, 0, 0, 0, 0, 195, 0, - 0, 2413, 736, 2416, 0, 0, 2082, 0, 0, 0, - 0, 0, 736, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 736, 0, 736, 0, 0, - 0, 0, 0, 0, 0, 736, 0, 0, 1528, 736, - 3312, 0, 736, 736, 736, 736, 0, 736, 0, 736, - 736, 0, 736, 736, 736, 736, 736, 736, 0, 0, - 0, 0, 0, 0, 0, 1528, 736, 736, 1528, 736, - 1528, 195, 736, 0, 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, 736, 0, 195, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 736, 0, 0, - 736, 0, 195, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3405, 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, 736, 3420, 0, 0, 0, 1024, - 0, 0, 0, 0, 0, 1025, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2137, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2082, 0, 0, 0, - 0, 0, 0, 2575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2596, 2597, 0, 0, 2601, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2606, 0, 0, 0, 0, 0, 0, 2609, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2612, 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, 1012, 1013, 1014, 1015, 1016, 1017, - 1018, 1019, 1020, 1021, 1022, 1023, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 736, 736, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 736, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3618, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3642, 0, 0, 0, - 736, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1528, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1528, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3662, 0, 3663, 0, 3664, 0, - 3665, 0, 0, 0, 0, 0, 0, 0, 3668, 3669, - 0, 0, 0, 0, 0, 0, 0, 0, 3674, 0, - 0, 958, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3675, 0, 3676, 0, 3677, 0, 3678, 0, - 3679, 0, 3680, 0, 3681, 0, 3682, 0, 3683, 0, - 3684, 0, 3685, 0, 3686, 0, 3687, 0, 3688, 0, - 3689, 0, 3690, 0, 0, 3691, 0, 0, 0, 3692, - 0, 3693, 0, 0, 0, 0, 0, 3695, 0, 0, - 0, 0, 0, 713, 0, 0, 0, 0, 0, 735, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3712, - 0, 0, 0, 0, 2343, 0, 0, 0, 3717, 0, - 3718, 3719, 0, 3720, 0, 3721, 0, 0, 0, 0, - 3722, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 735, 0, 0, 0, 3751, 195, 0, - 0, 0, 0, 736, 0, 0, 0, 0, 0, 0, - 3760, 0, 0, 3762, 0, 0, 2917, 0, 0, 0, - 0, 0, 0, 0, 0, 3766, 0, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 736, 0, 0, 0, - 0, 3902, 0, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 0, 0, 736, 0, 0, 2343, 195, 0, - 195, 0, 195, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 736, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2966, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 736, 0, 0, 0, 0, - 0, 0, 736, 736, 736, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3014, 3015, 3016, - 3017, 3018, 3019, 736, 0, 0, 0, 0, 0, 736, - 736, 0, 0, 736, 0, 736, 0, 0, 0, 0, - 4012, 736, 0, 0, 0, 0, 2082, 3030, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3038, 0, 0, 0, 0, 736, 0, 0, 0, - 0, 736, 0, 0, 0, 736, 736, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, - 195, 0, 0, 0, 0, 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, 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, - 195, 0, 0, 0, 0, 0, 0, 195, 0, 0, - 0, 0, 736, 95, 0, 0, 1024, 0, 0, 0, - 0, 964, 1025, 977, 978, 979, 965, 0, 0, 966, - 967, 0, 968, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 973, 0, - 980, 981, 0, 0, 0, 0, 0, 4054, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1528, 0, 2343, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3348, - 3349, 0, 0, 4068, 0, 0, 4069, 0, 4070, 0, - 0, 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, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, - 1021, 1022, 1023, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3350, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4154, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3302, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4170, - 0, 4171, 0, 4172, 0, 0, 0, 0, 0, 0, - 0, 3340, 0, 0, 0, 735, 1439, 735, 735, 0, - 0, 0, 0, 0, 0, 3354, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3351, 3352, 0, 0, 735, - 0, 0, 0, 0, 0, 0, 3372, 0, 0, 3375, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1527, 0, - 0, 195, 0, 4221, 0, 4222, 0, 0, 0, 195, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 736, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 736, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 929, 0, 0, 0, 0, 0, 933, 0, 195, 0, - 930, 931, 0, 195, 0, 932, 934, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 915, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 736, 0, 0, 0, 0, 0, 195, 0, - 0, 0, 0, 0, 3535, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 734, 736, - 0, 0, 0, 0, 0, 0, 736, 0, 0, 0, - 736, 736, 0, 0, 0, 736, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1528, 736, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, - 1096, 0, 1103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3596, - 0, 0, 0, 195, 195, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3611, - 0, 3612, 3613, 3614, 0, 0, 0, 0, 195, 0, - 0, 0, 0, 735, 735, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 736, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 735, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 735, - 0, 0, 0, 0, 736, 0, 0, 0, 0, 735, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 735, 0, 735, 0, 0, 0, 0, 0, - 0, 0, 735, 0, 0, 1527, 735, 0, 0, 735, - 735, 735, 735, 0, 735, 0, 735, 735, 0, 735, - 735, 735, 735, 735, 735, 0, 0, 0, 0, 0, - 0, 0, 1527, 735, 735, 1527, 735, 1527, 0, 735, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 0, 0, 0, 736, - 0, 0, 0, 0, 735, 0, 0, 735, 0, 0, - 0, 736, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 736, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 0, 195, 0, 0, - 736, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 736, 0, 0, 0, 1528, 0, - 0, 736, 736, 1528, 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, 0, 0, 0, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 736, 0, 0, 1528, 0, - 0, 0, 0, 736, 0, 0, 0, 0, 195, 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, 195, 0, 0, 195, 0, 0, 0, - 0, 735, 735, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 735, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 735, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1527, 0, 0, - 0, 0, 0, 0, 0, 0, 2146, 0, 0, 0, - 0, 0, 0, 0, 0, 1527, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 736, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1284, 0, 1284, 1284, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1453, 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, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 916, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4052, 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, 735, 0, 0, 0, 0, 195, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 193, 0, 0, 678, 0, 0, 195, 0, 195, 195, - 195, 0, 0, 0, 0, 0, 0, 0, 736, 736, - 0, 0, 0, 678, 0, 0, 0, 0, 0, 0, - 735, 0, 0, 0, 0, 0, 0, 0, 0, 1052, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1072, 1072, 0, 0, - 0, 0, 0, 735, 0, 678, 0, 736, 736, 736, - 736, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 735, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 735, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 735, 0, 0, 0, 0, 0, 0, 735, - 735, 735, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 735, 0, 1726, 1727, 0, 0, 735, 735, 0, 0, - 735, 0, 735, 0, 0, 0, 0, 0, 735, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1780, 0, 736, 0, 736, 0, 195, 0, - 0, 0, 0, 735, 0, 0, 0, 1798, 735, 0, - 0, 0, 735, 735, 0, 0, 0, 1528, 1857, 0, - 0, 195, 0, 0, 736, 0, 736, 0, 1866, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1096, 0, 1893, 0, 0, 0, 0, 0, 0, - 0, 1902, 0, 0, 0, 1904, 0, 0, 1907, 1908, - 1910, 1910, 0, 1910, 0, 1910, 1910, 0, 1919, 1910, - 1910, 1910, 1910, 1910, 736, 0, 0, 0, 0, 0, - 0, 0, 1939, 1940, 0, 1096, 0, 195, 1945, 0, - 736, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 736, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 735, - 1987, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2009, 0, 0, 2013, 0, 0, 0, + 1656, 1657, 1658, 1659, 1660, 1662, 1663, 1664, 1665, 1666, + 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, + 1677, 1683, 1684, 1685, 1686, 1700, 1701, 1702, 1703, 1704, + 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 3997, + 4042, 3247, 4026, 4016, 4025, 0, 3247, 0, 1754, 4045, + 4022, 0, 4024, 4060, 0, 0, 0, 0, 0, 0, + 0, 3929, 1762, 0, 0, 1755, 0, 0, 0, 0, + 3250, 87, 0, 0, 0, 0, 0, 0, 0, 0, + 4044, 0, 0, 0, 1726, 0, 0, 0, 3268, 0, + 1750, 1751, 1761, 1759, 1760, 1756, 4062, 1757, 4049, 0, + 0, 0, 4065, 0, 0, 0, 0, 0, 0, 0, + 0, 3933, 0, 0, 0, 0, 0, 0, 0, 4067, + 1758, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4074, 0, 0, 42, 0, 0, 0, 0, 4084, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1229, 4085, 1235, 0, 4086, 0, 0, 0, 4110, + 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4095, 0, 0, 4104, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4046, 0, 1493, 0, 0, 0, 0, + 1726, 3953, 4130, 4141, 4127, 4119, 3399, 4124, 4121, 4120, + 4118, 4123, 4114, 4122, 4116, 1463, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1551, 0, 3416, 3417, + 3247, 3418, 3420, 3422, 4149, 4172, 42, 0, 4162, 0, + 0, 0, 0, 0, 4154, 4167, 0, 0, 0, 0, + 0, 0, 0, 4180, 0, 0, 0, 0, 0, 3435, + 4141, 4182, 4193, 0, 3438, 0, 3440, 3441, 3442, 3444, + 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, + 3455, 3456, 3458, 3460, 3462, 3464, 3466, 3468, 3470, 3472, + 3474, 3476, 3478, 3480, 3482, 3484, 3486, 3488, 3489, 3491, + 3492, 3493, 3495, 4197, 4216, 3497, 4192, 3499, 3500, 3501, + 4111, 2153, 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, + 3513, 3514, 3515, 4222, 2151, 4229, 4226, 4227, 4225, 4223, + 2031, 3521, 4213, 4051, 4212, 3526, 4106, 4141, 4237, 3530, + 3531, 0, 3532, 3534, 0, 3537, 3539, 4251, 3541, 3542, + 3543, 3544, 0, 4253, 3244, 4245, 0, 0, 3552, 0, + 1032, 0, 0, 2347, 0, 0, 1033, 4070, 0, 2153, + 0, 0, 4261, 0, 0, 0, 2152, 4262, 4263, 0, + 3993, 0, 2151, 0, 4260, 0, 0, 0, 0, 4058, + 0, 0, 0, 3576, 3577, 0, 0, 3581, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4188, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4196, 0, 0, 0, 0, 0, 0, 0, 0, 1841, + 0, 0, 0, 0, 4105, 989, 990, 991, 992, 993, + 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, + 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 0, 0, 0, + 0, 0, 3656, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1789, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3675, 0, 0, + 3679, 0, 0, 0, 1801, 0, 0, 1878, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1818, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3692, 0, 0, 4210, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1828, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 965, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3715, 0, + 0, 0, 0, 0, 0, 0, 1959, 0, 0, 0, + 0, 3723, 0, 0, 0, 0, 0, 0, 3730, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2036, 197, 0, 0, 197, + 1842, 2004, 0, 736, 0, 0, 0, 0, 742, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2032, 197, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2043, 197, 0, 0, 0, 0, + 0, 2047, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 0, + 0, 0, 742, 197, 742, 0, 1855, 1858, 1859, 1860, + 1861, 1862, 1863, 0, 1864, 1865, 1867, 1868, 1866, 1869, + 1870, 1843, 1844, 1845, 1846, 1826, 1827, 1856, 0, 1829, + 0, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, + 0, 0, 1839, 1847, 1848, 1849, 1850, 3942, 1851, 1852, + 1853, 1854, 0, 0, 1840, 0, 3949, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3959, 3960, 3961, 0, + 3963, 0, 3964, 3965, 0, 0, 0, 0, 3968, 3969, + 3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, + 3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, + 0, 3991, 3994, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4003, 4004, 4005, + 4006, 4007, 4009, 4010, 4012, 4014, 4015, 4017, 0, 0, + 0, 4021, 0, 0, 0, 4023, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4050, 0, 2104, 2105, 2106, 2107, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2097, 0, 0, 2120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2159, 2160, 0, 0, 0, 0, 2183, + 0, 0, 2187, 2188, 0, 0, 0, 2193, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1857, + 0, 0, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, + 2213, 2214, 0, 2216, 0, 0, 0, 2238, 2239, 2240, + 2241, 2242, 2243, 2244, 2245, 2247, 0, 2252, 0, 2254, + 2255, 2256, 0, 2258, 2259, 2260, 0, 2262, 2263, 2264, + 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, + 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, + 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, + 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, + 2305, 2306, 2307, 2311, 2312, 2313, 2314, 2315, 2316, 2317, + 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, + 2328, 2329, 2330, 2331, 2332, 2333, 0, 0, 0, 0, + 0, 2339, 0, 2341, 0, 2348, 2349, 2350, 2351, 2352, + 2353, 0, 0, 0, 0, 0, 0, 4075, 0, 0, + 0, 0, 0, 0, 2364, 2365, 2366, 2367, 2368, 2369, + 2370, 2371, 0, 2373, 2374, 2375, 2376, 2377, 0, 0, + 0, 4090, 0, 0, 0, 0, 0, 4093, 0, 4094, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4109, 1080, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 192, 4135, 4136, + 0, 0, 0, 0, 0, 0, 0, 0, 2997, 2420, + 2421, 0, 4143, 4145, 4147, 0, 0, 0, 0, 0, + 131, 0, 153, 0, 0, 0, 0, 0, 0, 0, + 4153, 0, 192, 0, 0, 2459, 174, 0, 0, 0, + 0, 2426, 4175, 0, 0, 0, 0, 0, 0, 2430, + 0, 2433, 0, 0, 2097, 131, 0, 153, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 164, 174, 0, 0, 0, 0, 152, 0, 0, 0, + 4194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 0, 197, 0, 0, 171, 2502, 0, 172, + 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, + 0, 152, 0, 0, 4217, 4219, 4221, 0, 0, 0, + 0, 1900, 1901, 163, 162, 191, 0, 0, 0, 0, + 742, 171, 742, 742, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4242, 0, 0, + 0, 0, 0, 0, 742, 197, 140, 141, 163, 162, + 191, 0, 0, 0, 0, 4254, 4255, 0, 0, 0, + 0, 0, 0, 0, 86, 44, 45, 88, 0, 0, + 0, 0, 0, 1537, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 92, 0, 0, 0, 48, 76, 77, + 0, 74, 78, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 97, 0, 157, 1902, 160, + 1032, 1899, 0, 158, 159, 0, 1033, 0, 0, 0, + 175, 0, 0, 0, 0, 62, 2152, 0, 0, 181, + 0, 0, 0, 0, 2097, 0, 0, 95, 0, 0, + 0, 2592, 157, 138, 160, 145, 137, 0, 158, 159, + 0, 0, 2613, 2614, 0, 175, 2618, 0, 0, 0, + 0, 0, 0, 0, 181, 146, 0, 0, 2623, 0, + 0, 0, 0, 0, 0, 2626, 0, 0, 0, 149, + 147, 142, 143, 144, 148, 0, 0, 83, 0, 0, + 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, + 150, 2629, 0, 0, 0, 989, 990, 991, 992, 993, + 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, + 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, + 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, 0, + 0, 82, 79, 166, 0, 2678, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2684, 2685, 2686, 2687, 0, + 0, 0, 0, 0, 0, 61, 91, 90, 0, 0, + 71, 72, 58, 0, 0, 0, 197, 0, 80, 81, + 742, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1841, 0, 0, 0, 197, + 1551, 0, 0, 0, 161, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 742, 63, 64, 197, 65, 66, 67, 68, 0, + 0, 0, 0, 0, 0, 0, 742, 0, 0, 161, + 0, 0, 0, 197, 0, 0, 0, 742, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 742, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 742, 0, 742, 0, 0, 0, 0, 0, 0, 60, + 742, 0, 0, 1537, 742, 0, 0, 742, 742, 742, + 742, 0, 742, 0, 742, 742, 0, 742, 742, 742, + 742, 742, 742, 154, 0, 0, 155, 0, 0, 0, + 1537, 742, 742, 1537, 742, 1537, 197, 742, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 197, 167, 154, 0, + 0, 155, 1828, 0, 179, 0, 0, 0, 0, 742, + 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 742, 0, 0, 742, 1789, 197, 197, 89, + 0, 0, 167, 0, 0, 0, 0, 0, 0, 179, + 0, 0, 0, 0, 197, 187, 0, 0, 0, 0, + 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 742, + 0, 0, 0, 0, 0, 0, 2936, 0, 0, 0, + 187, 0, 0, 0, 0, 0, 1842, 0, 0, 0, + 0, 0, 168, 173, 170, 176, 177, 178, 180, 182, + 183, 184, 185, 0, 0, 0, 0, 0, 186, 188, + 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 168, 173, 170, + 176, 177, 178, 180, 182, 183, 184, 185, 0, 94, + 0, 0, 0, 186, 188, 189, 190, 0, 0, 0, + 0, 2985, 1855, 1858, 1859, 1860, 1861, 1862, 1863, 0, + 1864, 1865, 1867, 1868, 1866, 1869, 1870, 1843, 1844, 1845, + 1846, 1826, 1827, 1856, 0, 1829, 0, 1830, 1831, 1832, + 1833, 1834, 1835, 1836, 1837, 1838, 0, 0, 1839, 1847, + 1848, 1849, 1850, 0, 1851, 1852, 1853, 1854, 0, 0, + 1840, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3033, 3034, 3035, + 3036, 3037, 3038, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 742, + 742, 0, 0, 0, 0, 0, 2097, 3049, 0, 3061, + 70, 0, 0, 0, 742, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, + 0, 3057, 0, 0, 0, 0, 3087, 3088, 3089, 0, + 0, 3091, 0, 0, 3093, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3112, 3113, 3114, 0, 0, 0, + 0, 0, 0, 3119, 0, 742, 0, 0, 3121, 0, + 0, 3123, 3124, 3125, 0, 1537, 0, 3126, 3127, 0, + 0, 3128, 0, 3129, 0, 0, 0, 0, 0, 0, + 3130, 0, 3131, 1537, 0, 0, 3132, 0, 3133, 0, + 0, 3134, 0, 3135, 0, 3136, 0, 3137, 0, 3138, + 0, 3139, 0, 3140, 0, 3141, 0, 3142, 0, 3143, + 0, 3144, 0, 3145, 0, 3146, 0, 3147, 0, 3148, + 0, 3149, 0, 3150, 0, 3151, 0, 0, 0, 3152, + 0, 3153, 0, 3154, 0, 0, 3155, 0, 3156, 0, + 3157, 0, 2311, 3159, 0, 1857, 3161, 0, 0, 3163, + 3164, 3165, 3166, 0, 0, 0, 0, 3167, 2311, 2311, + 2311, 2311, 2311, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3177, 0, 0, 0, 0, 0, 0, + 0, 3190, 0, 0, 3194, 0, 0, 0, 0, 0, + 0, 0, 0, 3197, 3198, 3199, 3200, 3201, 3202, 0, + 0, 0, 3203, 3204, 0, 3205, 0, 3206, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2358, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1080, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 964, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3239, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 197, 0, 0, 0, 0, 742, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3269, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, + 0, 0, 742, 0, 0, 0, 719, 0, 0, 0, + 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 0, 0, 0, 742, 0, 0, 2358, 197, + 0, 197, 0, 197, 197, 0, 0, 0, 0, 3331, + 0, 0, 0, 0, 0, 0, 0, 0, 742, 0, + 0, 0, 0, 0, 0, 0, 0, 3321, 0, 0, + 0, 0, 0, 0, 0, 0, 741, 0, 741, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3359, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3373, 0, 0, + 0, 0, 0, 0, 0, 0, 742, 0, 0, 0, + 0, 0, 0, 742, 742, 742, 197, 0, 3391, 0, + 0, 3394, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 742, 0, 3424, 0, 0, 0, + 742, 742, 0, 0, 742, 0, 742, 0, 0, 0, + 0, 0, 742, 0, 921, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3439, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 742, 0, 0, + 0, 0, 742, 0, 0, 0, 742, 742, 0, 0, + 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1896, 0, 0, 0, 0, + 0, 0, 740, 0, 0, 0, 0, 131, 0, 153, + 0, 0, 0, 0, 197, 0, 0, 0, 0, 0, + 0, 197, 0, 174, 0, 0, 0, 0, 0, 0, + 0, 0, 197, 197, 0, 0, 197, 0, 197, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, + 0, 0, 0, 0, 0, 197, 1105, 164, 1112, 0, + 0, 0, 0, 152, 0, 0, 3554, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 0, 171, 0, 0, 172, 0, 197, 0, + 0, 0, 0, 742, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1900, 1901, + 163, 162, 191, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3615, 3637, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1537, 0, 2358, + 0, 3630, 0, 3631, 3632, 3633, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3661, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 157, 1902, 160, 0, 1899, 0, + 158, 159, 0, 0, 0, 0, 0, 175, 0, 0, + 0, 0, 0, 0, 0, 0, 181, 0, 0, 0, + 0, 0, 0, 3681, 0, 3682, 0, 3683, 0, 3684, + 0, 0, 0, 0, 0, 0, 0, 3687, 3688, 0, + 0, 0, 0, 0, 0, 0, 0, 3693, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3694, 0, 3695, 0, 3696, 0, 3697, 0, 3698, + 0, 3699, 0, 3700, 0, 3701, 0, 3702, 0, 3703, + 0, 3704, 0, 3705, 0, 3706, 0, 3707, 0, 3708, + 0, 3709, 0, 0, 3710, 0, 0, 0, 3711, 0, + 3712, 0, 0, 0, 0, 0, 3714, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3731, 0, + 0, 0, 0, 0, 0, 0, 0, 3736, 0, 3737, + 3738, 0, 3739, 0, 3740, 166, 0, 0, 0, 3741, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 197, 0, 0, 0, 3770, 0, 0, 0, + 197, 0, 0, 0, 0, 0, 0, 0, 0, 3779, + 0, 742, 3781, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3785, 0, 0, 742, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3921, 0, 0, 0, 741, 1448, 741, 741, 0, 0, + 0, 197, 0, 0, 0, 0, 197, 0, 0, 0, + 0, 161, 0, 0, 0, 0, 0, 0, 741, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1536, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 742, 0, 0, 0, 0, + 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 742, 0, 0, 0, 0, 0, 0, 742, + 0, 0, 0, 742, 742, 0, 0, 0, 742, 0, + 154, 0, 0, 155, 0, 0, 0, 0, 0, 4031, + 0, 0, 0, 0, 1537, 742, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 197, 197, 197, + 197, 197, 197, 0, 167, 0, 0, 0, 0, 0, + 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 197, 197, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 187, 0, 1293, 0, 1293, 1293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 742, 1462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, + 173, 170, 176, 177, 178, 180, 182, 183, 184, 185, + 0, 0, 0, 0, 0, 186, 188, 189, 190, 0, + 0, 0, 0, 0, 0, 0, 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 736, 0, - 1284, 0, 0, 0, 0, 736, 0, 736, 0, 0, - 0, 0, 0, 1527, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 741, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 741, 4071, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 741, 4087, 0, 0, 4088, 0, 4089, 0, 0, + 0, 741, 742, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 742, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 741, 0, 741, 0, 0, 0, + 0, 0, 0, 0, 741, 0, 0, 1536, 741, 0, + 0, 741, 741, 741, 741, 742, 741, 0, 741, 741, + 0, 741, 741, 741, 741, 741, 741, 0, 0, 0, + 197, 0, 0, 742, 1536, 741, 741, 1536, 741, 1536, + 0, 741, 0, 0, 0, 0, 0, 0, 0, 742, + 0, 0, 0, 1537, 0, 0, 742, 742, 1537, 197, + 197, 197, 197, 197, 0, 0, 0, 0, 0, 4173, + 0, 197, 0, 741, 0, 0, 0, 197, 0, 197, + 0, 0, 197, 197, 197, 0, 741, 0, 0, 741, + 0, 0, 0, 0, 0, 0, 0, 0, 4189, 0, + 4190, 0, 4191, 0, 1736, 1737, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, + 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, + 742, 0, 0, 1537, 0, 1795, 0, 0, 742, 0, + 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, + 1813, 0, 0, 0, 0, 0, 0, 197, 0, 0, + 0, 1872, 4240, 0, 4241, 0, 0, 0, 0, 0, + 0, 1881, 0, 0, 0, 0, 0, 0, 197, 0, + 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1105, 0, 1908, 0, 0, 0, + 0, 0, 0, 0, 1917, 0, 0, 0, 1919, 0, + 0, 1922, 1923, 1925, 1925, 0, 1925, 0, 1925, 1925, + 0, 1934, 1925, 1925, 1925, 1925, 1925, 0, 0, 0, + 0, 0, 0, 0, 0, 1954, 1955, 0, 1105, 0, + 0, 1960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 922, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2002, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2024, 0, 0, 2028, + 0, 0, 0, 741, 741, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 741, 742, + 0, 0, 0, 0, 0, 0, 195, 0, 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1293, 0, 0, 0, 0, 0, 684, + 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, + 0, 0, 0, 0, 0, 1060, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 741, + 0, 0, 0, 0, 1081, 1081, 0, 0, 0, 1536, + 0, 0, 0, 684, 0, 0, 0, 0, 2161, 0, + 0, 0, 0, 0, 0, 0, 0, 1536, 0, 0, + 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 0, 197, 197, 197, 0, 0, 0, 0, + 0, 0, 0, 742, 742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1284, 1284, 0, 0, 0, 0, 736, 0, 0, 0, - 0, 0, 0, 0, 0, 2070, 0, 0, 0, 678, - 0, 678, 195, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1293, 1293, 0, 0, 0, 0, 0, + 0, 0, 742, 742, 742, 742, 0, 0, 2085, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 736, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2132, 0, 0, 0, - 0, 0, 0, 678, 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 736, 0, 0, 0, - 0, 1529, 0, 0, 0, 0, 736, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1528, 736, 0, 736, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147, + 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2930, 0, 0, 0, - 0, 0, 0, 0, 736, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 741, + 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 195, 736, 0, 0, 735, + 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 742, + 0, 742, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1537, 0, 0, 0, 197, 0, 0, 742, + 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 741, 0, 0, 0, 0, 0, 0, 741, 741, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 735, 0, 0, 0, - 0, 0, 0, 735, 0, 0, 736, 735, 735, 0, - 1284, 0, 735, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1527, 735, - 736, 0, 0, 0, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 736, - 0, 736, 0, 0, 0, 0, 0, 0, 0, 2380, + 0, 0, 0, 1293, 0, 0, 0, 0, 741, 0, + 0, 0, 0, 0, 741, 741, 0, 0, 741, 0, + 741, 0, 0, 0, 0, 0, 741, 0, 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 197, 0, 0, 742, 0, 0, 0, 0, + 0, 0, 0, 2395, 0, 0, 0, 0, 742, 0, + 0, 741, 0, 0, 0, 0, 741, 0, 0, 0, + 741, 741, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1795, + 0, 0, 1293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2393, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1105, 742, 0, 0, 0, 0, 0, 0, + 742, 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1780, 0, 0, 1284, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1096, 0, 0, 0, 0, 0, 0, - 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1052, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 678, - 0, 1103, 0, 0, 0, 0, 0, 0, 2506, 2507, - 2508, 0, 0, 0, 0, 0, 0, 0, 678, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1096, - 0, 0, 0, 0, 0, 1103, 1902, 0, 0, 1902, - 0, 1902, 0, 0, 0, 0, 0, 2539, 0, 0, + 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 741, 0, 0, + 1112, 0, 0, 0, 0, 0, 0, 2523, 2524, 2525, + 0, 684, 0, 684, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1105, 0, + 0, 0, 0, 0, 1112, 1917, 0, 0, 1917, 0, + 1917, 0, 0, 0, 0, 0, 2556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1096, 0, 0, 0, 0, 2132, 0, 0, - 0, 2132, 2132, 0, 0, 1529, 735, 0, 1529, 0, - 1529, 678, 0, 0, 0, 0, 0, 0, 735, 0, + 0, 1536, 0, 741, 0, 684, 0, 0, 0, 0, + 0, 1105, 0, 0, 0, 0, 2147, 0, 0, 0, + 2147, 2147, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1961, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 678, 0, 0, 735, + 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2015, 678, 0, 0, 0, 735, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 678, - 0, 735, 0, 0, 0, 1527, 678, 0, 735, 735, - 1527, 0, 0, 0, 0, 2041, 2042, 678, 678, 678, - 678, 678, 678, 678, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2617, 0, + 0, 0, 0, 0, 0, 742, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 735, 0, 0, 1527, 0, 0, 0, 0, - 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1284, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1537, 742, 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 742, + 2358, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 197, 742, 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 684, 0, 0, 0, + 0, 0, 0, 0, 0, 742, 2949, 0, 0, 0, + 197, 0, 0, 0, 0, 0, 0, 0, 0, 1060, + 0, 0, 0, 0, 742, 0, 742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 684, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 741, + 0, 0, 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 741, 0, 0, 0, + 0, 0, 0, 741, 0, 0, 0, 741, 741, 0, + 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1538, 0, 0, 0, 0, 1536, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1538, 0, 0, 1538, 0, 1538, 684, 0, 0, 0, + 0, 0, 0, 0, 0, 2882, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1976, 0, 0, 0, + 0, 2899, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2030, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 741, 0, 0, 684, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, + 2056, 2057, 684, 684, 684, 684, 684, 684, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, - 1529, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1529, 0, + 0, 741, 0, 0, 0, 0, 0, 0, 0, 2981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2408, 0, 0, 0, + 0, 0, 0, 3005, 0, 0, 0, 1917, 1917, 0, + 0, 0, 3010, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2880, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3586, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 741, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 741, + 0, 2147, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 684, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 735, 735, 0, 0, 0, - 0, 0, 0, 0, 2015, 0, 0, 0, 0, 0, + 0, 0, 0, 741, 0, 0, 0, 1536, 0, 0, + 741, 741, 1536, 0, 0, 0, 0, 0, 0, 0, + 0, 2147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2962, 0, - 0, 0, 0, 0, 735, 735, 735, 735, 1961, 0, + 0, 0, 0, 1538, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1072, 2393, 0, 0, 0, 0, - 0, 0, 2986, 0, 0, 0, 1902, 1902, 0, 0, - 0, 2991, 0, 1052, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3002, 0, - 678, 0, 0, 0, 0, 0, 0, 2015, 678, 0, - 678, 0, 678, 2432, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 741, 0, 0, 1536, 0, 0, + 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3179, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1293, 0, + 0, 0, 0, 0, 0, 3398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3224, 0, 2030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1293, 0, 0, 0, 0, 0, 0, + 3251, 1925, 0, 0, 0, 0, 0, 0, 0, 95, + 0, 0, 1032, 0, 0, 0, 0, 970, 1033, 984, + 985, 986, 971, 0, 1976, 972, 973, 0, 974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1081, 0, 0, 0, 979, 0, 987, 988, 0, 0, + 0, 0, 0, 741, 0, 0, 0, 0, 0, 1060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2132, 0, 0, 0, 0, 2509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 735, 0, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 1105, 0, 0, 0, 2030, 684, + 0, 684, 2408, 684, 2449, 3367, 3368, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 989, 990, 991, + 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, + 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, + 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, + 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1527, 0, 0, 0, 0, 0, - 2132, 735, 0, 735, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3605, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3369, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 741, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 678, 0, 0, 0, 735, 0, 0, - 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 735, 678, 678, 0, 0, 678, 0, 2603, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 678, 0, 0, - 0, 0, 0, 0, 678, 3160, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1284, 0, 0, + 0, 0, 0, 0, 0, 0, 741, 741, 741, 741, + 0, 0, 0, 1872, 0, 0, 0, 0, 0, 0, + 0, 3370, 3371, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 678, 0, 0, 0, 0, 0, 0, 2614, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1910, 0, - 0, 0, 0, 0, 0, 735, 0, 0, 0, 0, - 0, 0, 735, 0, 735, 0, 3205, 0, 0, 0, + 0, 0, 0, 0, 684, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 684, 684, 0, 0, 684, 0, 2620, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 684, 0, + 0, 0, 0, 0, 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1284, 0, 0, 0, 0, 0, 0, 3232, 1910, 0, - 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 935, 0, 0, 0, + 0, 684, 939, 0, 0, 0, 936, 937, 2631, 0, + 0, 938, 940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1529, 0, 2015, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2408, 2408, 0, + 0, 0, 0, 741, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1536, 1538, 0, 2030, + 0, 0, 0, 741, 0, 741, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3669, 3670, 3671, 3672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1096, 0, 0, 0, 0, 0, 0, 0, 2393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 741, 0, 0, + 0, 0, 0, 0, 741, 0, 741, 0, 0, 0, + 0, 0, 0, 3747, 0, 3747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, + 0, 0, 0, 3775, 0, 3777, 0, 0, 0, 0, + 0, 0, 684, 0, 0, 0, 0, 0, 0, 0, + 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, - 0, 678, 0, 735, 0, 0, 0, 0, 0, 1961, - 1857, 0, 0, 1527, 735, 0, 735, 0, 0, 0, + 0, 0, 0, 2408, 0, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 0, 0, 684, 0, 0, 3944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 735, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 678, 0, - 0, 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3747, 0, 741, + 0, 0, 0, 0, 3747, 0, 3747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 678, 0, - 0, 0, 0, 0, 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2393, 2393, 735, 0, 735, 0, + 0, 0, 0, 0, 1538, 2408, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 684, 684, 684, + 684, 684, 684, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 741, 684, 684, 0, 0, + 0, 0, 0, 0, 0, 1536, 741, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 741, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 678, 678, 678, 678, 678, 678, - 0, 0, 0, 3650, 3651, 3652, 3653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 678, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 678, 0, + 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2408, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 741, 0, + 741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4091, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4099, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2408, 0, 4107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1293, 1293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1081, 0, + 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4157, 0, 0, 0, 0, + 0, 0, 0, 1538, 0, 0, 0, 0, 1538, 684, + 684, 684, 684, 684, 0, 0, 0, 0, 0, 0, + 0, 3267, 0, 0, 0, 0, 0, 1976, 0, 684, + 0, 0, 684, 3275, 2030, 4099, 0, 0, 0, 3807, + 3809, 3808, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3810, + 3811, 812, 0, 0, 0, 0, 0, 0, 0, 2408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 684, 1872, 0, + 4157, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1538, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 684, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 684, 0, + 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3728, 0, 3728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3756, 0, 3758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2393, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3925, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1284, - 0, 0, 0, 0, 0, 1072, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1529, 0, - 0, 0, 0, 1529, 678, 678, 678, 678, 678, 0, - 0, 0, 0, 0, 0, 0, 3248, 0, 0, 0, - 0, 0, 1961, 0, 678, 0, 0, 678, 3256, 2015, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3728, 0, 0, 0, 0, 0, - 0, 3728, 0, 3728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2393, 0, 0, 0, 0, 0, 1529, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3815, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3823, 3824, + 0, 0, 3899, 3898, 3897, 0, 684, 3895, 3896, 3894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 678, 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 684, 3900, 935, 0, 788, 789, 3901, 3902, + 939, 3903, 791, 792, 936, 937, 0, 786, 790, 938, + 940, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 684, 0, 684, 684, 684, 3804, 3805, 3806, 3812, + 3813, 3814, 3825, 3872, 3873, 3881, 3883, 891, 3882, 3884, + 3885, 3886, 3889, 3890, 3891, 3892, 3887, 3888, 3893, 3787, + 3791, 3788, 3789, 3790, 3802, 3792, 3793, 3794, 3795, 3796, + 3797, 3798, 3799, 3800, 3801, 3803, 3904, 3905, 3906, 3907, + 3908, 3909, 3818, 3822, 3821, 3819, 3820, 3816, 3817, 3844, + 3843, 3845, 3846, 3847, 3848, 3849, 3850, 3852, 3851, 3853, + 3854, 3855, 3856, 3857, 3858, 3826, 3827, 3830, 3831, 3829, + 3828, 3832, 3841, 3842, 3833, 3834, 3835, 3836, 3837, 3838, + 3840, 3839, 3859, 3860, 3861, 3862, 3863, 3865, 3864, 3868, + 3869, 3867, 3866, 3871, 3870, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 941, 0, + 942, 0, 0, 946, 0, 0, 0, 948, 947, 0, + 949, 911, 910, 0, 0, 943, 944, 0, 945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3910, 3911, 3912, + 3913, 3914, 3915, 3916, 3917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1538, 0, 0, 0, 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4072, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4080, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2393, 0, 4088, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1284, 1284, 3788, 3790, 3789, 3855, 3856, 3857, 3858, 3859, - 3860, 3861, 3791, 3792, 806, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 678, 0, 678, 678, - 678, 0, 4138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4080, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1857, 0, 4138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2883,4546 +2851,4543 @@ 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, 3796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3804, 3805, 0, 0, 3880, 3879, 3878, 1961, 0, - 3876, 3877, 3875, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1529, 0, 0, - 0, 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3881, 929, 0, 782, - 783, 3882, 3883, 933, 3884, 785, 786, 930, 931, 0, - 780, 784, 932, 934, 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, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3785, - 3786, 3787, 3793, 3794, 3795, 3806, 3853, 3854, 3862, 3864, - 885, 3863, 3865, 3866, 3867, 3870, 3871, 3872, 3873, 3868, - 3869, 3874, 3768, 3772, 3769, 3770, 3771, 3783, 3773, 3774, - 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3784, 3885, - 3886, 3887, 3888, 3889, 3890, 3799, 3803, 3802, 3800, 3801, - 3797, 3798, 3825, 3824, 3826, 3827, 3828, 3829, 3830, 3831, - 3833, 3832, 3834, 3835, 3836, 3837, 3838, 3839, 3807, 3808, - 3811, 3812, 3810, 3809, 3813, 3822, 3823, 3814, 3815, 3816, - 3817, 3818, 3819, 3821, 3820, 3840, 3841, 3842, 3843, 3844, - 3846, 3845, 3849, 3850, 3848, 3847, 3852, 3851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 935, 0, 936, 0, 0, 940, 0, 0, 0, - 942, 941, 0, 943, 905, 904, 0, 0, 937, 938, - 0, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3891, 3892, 3893, 3894, - 3895, 3896, 3897, 3898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, + 1976, 0, 0, 400, 0, 0, 0, 0, 0, 0, + 1431, 1415, 534, 0, 1357, 1434, 1325, 1344, 1444, 1347, + 1350, 1394, 1303, 1372, 420, 1341, 1329, 1298, 1336, 1299, + 1327, 1359, 273, 1324, 1417, 1376, 1433, 369, 270, 1305, + 1296, 206, 511, 1330, 435, 1346, 205, 1396, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 1440, 373, 1382, 0, 503, 405, 0, 0, + 2030, 1421, 1420, 1351, 1361, 1423, 1370, 1408, 1356, 1395, + 1313, 1381, 1435, 1342, 1391, 1436, 326, 250, 328, 204, + 417, 504, 289, 0, 0, 0, 0, 4131, 513, 966, + 0, 0, 0, 0, 4132, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 1338, 1388, + 616, 1430, 1339, 1390, 268, 324, 275, 267, 587, 1441, + 1422, 1302, 1369, 1429, 1364, 603, 0, 0, 231, 1432, + 1363, 0, 1393, 0, 1447, 1297, 1384, 0, 1300, 1304, + 1443, 1427, 1333, 278, 0, 0, 0, 0, 0, 0, + 0, 1360, 1371, 1405, 1409, 1354, 0, 0, 0, 0, + 0, 0, 0, 0, 1331, 0, 1380, 0, 0, 0, + 1309, 1301, 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, 0, 397, 0, - 0, 0, 0, 0, 0, 1422, 1406, 529, 0, 1348, - 1425, 1316, 1335, 1435, 1338, 1341, 1385, 1294, 1363, 417, - 1332, 1320, 1289, 1327, 1290, 1318, 1350, 271, 1315, 1408, - 1367, 1424, 367, 268, 1296, 1287, 204, 506, 1321, 431, - 1337, 203, 1387, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 1431, 371, 1373, - 0, 498, 402, 0, 0, 2015, 1412, 1411, 1342, 1352, - 1414, 1361, 1399, 1347, 1386, 1304, 1372, 1426, 1333, 1382, - 1427, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 4112, 508, 960, 0, 0, 0, 0, 4113, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 1329, 1379, 610, 1421, 1330, 1381, 266, - 322, 273, 265, 581, 1432, 1413, 1293, 1360, 1420, 1355, - 597, 0, 0, 229, 1423, 1354, 0, 1384, 0, 1438, - 1288, 1375, 0, 1291, 1295, 1434, 1418, 1324, 276, 0, - 0, 0, 0, 0, 0, 0, 1351, 1362, 1396, 1400, - 1345, 0, 0, 0, 0, 0, 0, 0, 0, 1322, - 0, 1371, 0, 0, 0, 1300, 1292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1349, - 0, 0, 0, 0, 1303, 0, 1323, 1397, 0, 1286, - 298, 1297, 403, 258, 0, 454, 1404, 1417, 1346, 630, - 1419, 1344, 1343, 1391, 1301, 1410, 1336, 366, 1299, 331, - 197, 225, 0, 1334, 413, 462, 474, 1409, 1319, 1328, - 254, 1326, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 1370, 1389, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 1298, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 1314, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 1405, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 1394, 1437, - 426, 473, 240, 607, 497, 199, 1308, 1313, 1306, 0, - 255, 256, 1376, 576, 1309, 1307, 1365, 1366, 1310, 1428, - 1429, 1430, 1415, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 1398, 1302, 0, 1311, 1312, 399, 1407, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 1369, 196, 221, - 369, 1433, 455, 289, 651, 619, 485, 614, 206, 223, - 1305, 263, 1317, 1325, 0, 1331, 1339, 1340, 1353, 1356, - 1357, 1358, 1359, 1377, 1378, 1380, 1388, 1390, 1393, 1395, - 1402, 1416, 1436, 198, 200, 209, 222, 232, 236, 243, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 1368, 1374, 382, 282, 306, 321, 1383, 618, 503, - 227, 467, 291, 251, 1401, 1403, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 1364, 1392, 377, 577, 578, 317, 397, 0, 0, 0, - 0, 0, 0, 1422, 1406, 529, 0, 1348, 1425, 1316, - 1335, 1435, 1338, 1341, 1385, 1294, 1363, 417, 1332, 1320, - 1289, 1327, 1290, 1318, 1350, 271, 1315, 1408, 1367, 1424, - 367, 268, 1296, 1287, 204, 506, 1321, 431, 1337, 203, - 1387, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 1431, 371, 1373, 0, 498, - 402, 0, 0, 0, 1412, 1411, 1342, 1352, 1414, 1361, - 1399, 1347, 1386, 1304, 1372, 1426, 1333, 1382, 1427, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 0, 508, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 1329, 1379, 610, 1421, 1330, 1381, 266, 322, 273, - 265, 581, 1432, 1413, 1293, 1360, 1420, 1355, 597, 0, - 0, 229, 1423, 1354, 0, 1384, 0, 1438, 1288, 1375, - 0, 1291, 1295, 1434, 1418, 1324, 276, 0, 0, 0, - 0, 0, 0, 0, 1351, 1362, 1396, 1400, 1345, 0, - 0, 0, 0, 0, 0, 3257, 0, 1322, 0, 1371, - 0, 0, 0, 1300, 1292, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1349, 0, 0, - 0, 0, 1303, 0, 1323, 1397, 0, 1286, 298, 1297, - 403, 258, 0, 454, 1404, 1417, 1346, 630, 1419, 1344, - 1343, 1391, 1301, 1410, 1336, 366, 1299, 331, 197, 225, - 0, 1334, 413, 462, 474, 1409, 1319, 1328, 254, 1326, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 1370, 1389, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 1298, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 1314, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 1405, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 1394, 1437, 426, 473, - 240, 607, 497, 199, 1308, 1313, 1306, 0, 255, 256, - 1376, 576, 1309, 1307, 1365, 1366, 1310, 1428, 1429, 1430, - 1415, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 1398, - 1302, 0, 1311, 1312, 399, 1407, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 1369, 196, 221, 369, 1433, - 455, 289, 651, 619, 485, 614, 206, 223, 1305, 263, - 1317, 1325, 0, 1331, 1339, 1340, 1353, 1356, 1357, 1358, - 1359, 1377, 1378, 1380, 1388, 1390, 1393, 1395, 1402, 1416, - 1436, 198, 200, 209, 222, 232, 236, 243, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 1368, - 1374, 382, 282, 306, 321, 1383, 618, 503, 227, 467, - 291, 251, 1401, 1403, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 1364, 1392, - 377, 577, 578, 317, 397, 0, 0, 0, 0, 0, - 0, 1422, 1406, 529, 0, 1348, 1425, 1316, 1335, 1435, - 1338, 1341, 1385, 1294, 1363, 417, 1332, 1320, 1289, 1327, - 1290, 1318, 1350, 271, 1315, 1408, 1367, 1424, 367, 268, - 1296, 1287, 204, 506, 1321, 431, 1337, 203, 1387, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 1431, 371, 1373, 0, 498, 402, 0, - 0, 0, 1412, 1411, 1342, 1352, 1414, 1361, 1399, 1347, - 1386, 1304, 1372, 1426, 1333, 1382, 1427, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 0, 508, - 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 1329, - 1379, 610, 1421, 1330, 1381, 266, 322, 273, 265, 581, - 1432, 1413, 1293, 1360, 1420, 1355, 597, 0, 0, 229, - 1423, 1354, 0, 1384, 0, 1438, 1288, 1375, 0, 1291, - 1295, 1434, 1418, 1324, 276, 0, 0, 0, 0, 0, - 0, 0, 1351, 1362, 1396, 1400, 1345, 0, 0, 0, - 0, 0, 0, 3218, 0, 1322, 0, 1371, 0, 0, - 0, 1300, 1292, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1349, 0, 0, 0, 0, - 1303, 0, 1323, 1397, 0, 1286, 298, 1297, 403, 258, - 0, 454, 1404, 1417, 1346, 630, 1419, 1344, 1343, 1391, - 1301, 1410, 1336, 366, 1299, 331, 197, 225, 0, 1334, - 413, 462, 474, 1409, 1319, 1328, 254, 1326, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 1370, 1389, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 1298, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 1314, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 1405, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 1394, 1437, 426, 473, 240, 607, - 497, 199, 1308, 1313, 1306, 0, 255, 256, 1376, 576, - 1309, 1307, 1365, 1366, 1310, 1428, 1429, 1430, 1415, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 1398, 1302, 0, - 1311, 1312, 399, 1407, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 1369, 196, 221, 369, 1433, 455, 289, - 651, 619, 485, 614, 206, 223, 1305, 263, 1317, 1325, - 0, 1331, 1339, 1340, 1353, 1356, 1357, 1358, 1359, 1377, - 1378, 1380, 1388, 1390, 1393, 1395, 1402, 1416, 1436, 198, - 200, 209, 222, 232, 236, 243, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 1368, 1374, 382, - 282, 306, 321, 1383, 618, 503, 227, 467, 291, 251, - 1401, 1403, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 1364, 1392, 377, 577, - 578, 317, 397, 0, 0, 0, 0, 0, 0, 1422, - 1406, 529, 0, 1348, 1425, 1316, 1335, 1435, 1338, 1341, - 1385, 1294, 1363, 417, 1332, 1320, 1289, 1327, 1290, 1318, - 1350, 271, 1315, 1408, 1367, 1424, 367, 268, 1296, 1287, - 204, 506, 1321, 431, 1337, 203, 1387, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 1431, 371, 1373, 0, 498, 402, 0, 0, 0, - 1412, 1411, 1342, 1352, 1414, 1361, 1399, 1347, 1386, 1304, - 1372, 1426, 1333, 1382, 1427, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 0, 0, 508, 960, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 1329, 1379, 610, - 1421, 1330, 1381, 266, 322, 273, 265, 581, 1432, 1413, - 1293, 1360, 1420, 1355, 597, 0, 0, 229, 1423, 1354, - 0, 1384, 0, 1438, 1288, 1375, 0, 1291, 1295, 1434, - 1418, 1324, 276, 0, 0, 0, 0, 0, 0, 0, - 1351, 1362, 1396, 1400, 1345, 0, 0, 0, 0, 0, - 0, 2411, 0, 1322, 0, 1371, 0, 0, 0, 1300, - 1292, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1349, 0, 0, 0, 0, 1303, 0, - 1323, 1397, 0, 1286, 298, 1297, 403, 258, 0, 454, - 1404, 1417, 1346, 630, 1419, 1344, 1343, 1391, 1301, 1410, - 1336, 366, 1299, 331, 197, 225, 0, 1334, 413, 462, - 474, 1409, 1319, 1328, 254, 1326, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 1370, 1389, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 1298, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 1314, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 1405, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 1394, 1437, 426, 473, 240, 607, 497, 199, - 1308, 1313, 1306, 0, 255, 256, 1376, 576, 1309, 1307, - 1365, 1366, 1310, 1428, 1429, 1430, 1415, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 1398, 1302, 0, 1311, 1312, - 399, 1407, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 1369, 196, 221, 369, 1433, 455, 289, 651, 619, - 485, 614, 206, 223, 1305, 263, 1317, 1325, 0, 1331, - 1339, 1340, 1353, 1356, 1357, 1358, 1359, 1377, 1378, 1380, - 1388, 1390, 1393, 1395, 1402, 1416, 1436, 198, 200, 209, - 222, 232, 236, 243, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 1368, 1374, 382, 282, 306, - 321, 1383, 618, 503, 227, 467, 291, 251, 1401, 1403, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 1364, 1392, 377, 577, 578, 317, - 397, 0, 0, 0, 0, 0, 0, 1422, 1406, 529, - 0, 1348, 1425, 1316, 1335, 1435, 1338, 1341, 1385, 1294, - 1363, 417, 1332, 1320, 1289, 1327, 1290, 1318, 1350, 271, - 1315, 1408, 1367, 1424, 367, 268, 1296, 1287, 204, 506, - 1321, 431, 1337, 203, 1387, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 1431, - 371, 1373, 0, 498, 402, 0, 0, 0, 1412, 1411, - 1342, 1352, 1414, 1361, 1399, 1347, 1386, 1304, 1372, 1426, - 1333, 1382, 1427, 324, 248, 326, 202, 414, 499, 287, - 0, 95, 0, 0, 0, 508, 725, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 1329, 1379, 610, 1421, 1330, - 1381, 266, 322, 273, 265, 581, 1432, 1413, 1293, 1360, - 1420, 1355, 597, 0, 0, 229, 1423, 1354, 0, 1384, - 0, 1438, 1288, 1375, 0, 1291, 1295, 1434, 1418, 1324, - 276, 0, 0, 0, 0, 0, 0, 0, 1351, 1362, - 1396, 1400, 1345, 0, 0, 0, 0, 0, 0, 0, - 0, 1322, 0, 1371, 0, 0, 0, 1300, 1292, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1349, 0, 0, 0, 0, 1303, 0, 1323, 1397, - 0, 1286, 298, 1297, 403, 258, 0, 454, 1404, 1417, - 1346, 630, 1419, 1344, 1343, 1391, 1301, 1410, 1336, 366, - 1299, 331, 197, 225, 0, 1334, 413, 462, 474, 1409, - 1319, 1328, 254, 1326, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 1370, 1389, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 1298, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 1314, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 1405, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 1394, 1437, 426, 473, 240, 607, 497, 199, 1308, 1313, - 1306, 0, 255, 256, 1376, 576, 1309, 1307, 1365, 1366, - 1310, 1428, 1429, 1430, 1415, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 1398, 1302, 0, 1311, 1312, 399, 1407, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 1369, - 196, 221, 369, 1433, 455, 289, 651, 619, 485, 614, - 206, 223, 1305, 263, 1317, 1325, 0, 1331, 1339, 1340, - 1353, 1356, 1357, 1358, 1359, 1377, 1378, 1380, 1388, 1390, - 1393, 1395, 1402, 1416, 1436, 198, 200, 209, 222, 232, - 236, 243, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 1368, 1374, 382, 282, 306, 321, 1383, - 618, 503, 227, 467, 291, 251, 1401, 1403, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 1364, 1392, 377, 577, 578, 317, 397, 0, - 0, 0, 0, 0, 0, 1422, 1406, 529, 0, 1348, - 1425, 1316, 1335, 1435, 1338, 1341, 1385, 1294, 1363, 417, - 1332, 1320, 1289, 1327, 1290, 1318, 1350, 271, 1315, 1408, - 1367, 1424, 367, 268, 1296, 1287, 204, 506, 1321, 431, - 1337, 203, 1387, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 1431, 371, 1373, - 0, 498, 402, 0, 0, 0, 1412, 1411, 1342, 1352, - 1414, 1361, 1399, 1347, 1386, 1304, 1372, 1426, 1333, 1382, - 1427, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 0, 508, 194, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 1329, 1379, 610, 1421, 1330, 1381, 266, - 322, 273, 265, 581, 1432, 1413, 1293, 1360, 1420, 1355, - 597, 0, 0, 229, 1423, 1354, 0, 1384, 0, 1438, - 1288, 1375, 0, 1291, 1295, 1434, 1418, 1324, 276, 0, - 0, 0, 0, 0, 0, 0, 1351, 1362, 1396, 1400, - 1345, 0, 0, 0, 0, 0, 0, 0, 0, 1322, - 0, 1371, 0, 0, 0, 1300, 1292, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1349, - 0, 0, 0, 0, 1303, 0, 1323, 1397, 0, 1286, - 298, 1297, 403, 258, 0, 454, 1404, 1417, 1346, 630, - 1419, 1344, 1343, 1391, 1301, 1410, 1336, 366, 1299, 331, - 197, 225, 0, 1334, 413, 462, 474, 1409, 1319, 1328, - 254, 1326, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 1370, 1389, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 1298, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 1314, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 1405, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 1394, 1437, - 426, 473, 240, 607, 497, 199, 1308, 1313, 1306, 0, - 255, 256, 1376, 576, 1309, 1307, 1365, 1366, 1310, 1428, - 1429, 1430, 1415, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 1398, 1302, 0, 1311, 1312, 399, 1407, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 1369, 196, 221, - 369, 1433, 455, 289, 651, 619, 485, 614, 206, 223, - 1305, 263, 1317, 1325, 0, 1331, 1339, 1340, 1353, 1356, - 1357, 1358, 1359, 1377, 1378, 1380, 1388, 1390, 1393, 1395, - 1402, 1416, 1436, 198, 200, 209, 222, 232, 236, 243, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 1368, 1374, 382, 282, 306, 321, 1383, 618, 503, - 227, 467, 291, 251, 1401, 1403, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 1364, 1392, 377, 577, 578, 317, 397, 0, 0, 0, - 0, 0, 0, 1422, 1406, 529, 0, 1348, 1425, 1316, - 1335, 1435, 1338, 1341, 1385, 1294, 1363, 417, 1332, 1320, - 1289, 1327, 1290, 1318, 1350, 271, 1315, 1408, 1367, 1424, - 367, 268, 1296, 1287, 204, 506, 1321, 431, 1337, 203, - 1387, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 1431, 371, 1373, 0, 498, - 402, 0, 0, 0, 1412, 1411, 1342, 1352, 1414, 1361, - 1399, 1347, 1386, 1304, 1372, 1426, 1333, 1382, 1427, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 0, 508, 725, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 1329, 1379, 610, 1421, 1330, 1381, 266, 322, 273, - 265, 581, 1432, 1413, 1293, 1360, 1420, 1355, 597, 0, - 0, 229, 1423, 1354, 0, 1384, 0, 1438, 1288, 1375, - 0, 1291, 1295, 1434, 1418, 1324, 276, 0, 0, 0, - 0, 0, 0, 0, 1351, 1362, 1396, 1400, 1345, 0, - 0, 0, 0, 0, 0, 0, 0, 1322, 0, 1371, - 0, 0, 0, 1300, 1292, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1349, 0, 0, - 0, 0, 1303, 0, 1323, 1397, 0, 1286, 298, 1297, - 403, 258, 0, 454, 1404, 1417, 1346, 630, 1419, 1344, - 1343, 1391, 1301, 1410, 1336, 366, 1299, 331, 197, 225, - 0, 1334, 413, 462, 474, 1409, 1319, 1328, 254, 1326, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 1370, 1389, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 1298, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 1314, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 1405, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 1394, 1437, 426, 473, - 240, 607, 497, 199, 1308, 1313, 1306, 0, 255, 256, - 1376, 576, 1309, 1307, 1365, 1366, 1310, 1428, 1429, 1430, - 1415, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 1398, - 1302, 0, 1311, 1312, 399, 1407, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 1369, 196, 221, 369, 1433, - 455, 289, 651, 619, 485, 614, 206, 223, 1305, 263, - 1317, 1325, 0, 1331, 1339, 1340, 1353, 1356, 1357, 1358, - 1359, 1377, 1378, 1380, 1388, 1390, 1393, 1395, 1402, 1416, - 1436, 198, 200, 209, 222, 232, 236, 243, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 1368, - 1374, 382, 282, 306, 321, 1383, 618, 503, 227, 467, - 291, 251, 1401, 1403, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 1364, 1392, - 377, 577, 578, 317, 397, 0, 0, 0, 0, 0, - 0, 1422, 1406, 529, 0, 1348, 1425, 1316, 1335, 1435, - 1338, 1341, 1385, 1294, 1363, 417, 1332, 1320, 1289, 1327, - 1290, 1318, 1350, 271, 1315, 1408, 1367, 1424, 367, 268, - 1296, 1287, 204, 506, 1321, 431, 1337, 203, 1387, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 1431, 371, 1373, 0, 498, 402, 0, - 0, 0, 1412, 1411, 1342, 1352, 1414, 1361, 1399, 1347, - 1386, 1304, 1372, 1426, 1333, 1382, 1427, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 0, 508, - 960, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 1329, - 1379, 610, 1421, 1330, 1381, 266, 322, 273, 265, 581, - 1432, 1413, 1293, 1360, 1420, 1355, 597, 0, 0, 229, - 1423, 1354, 0, 1384, 0, 1438, 1288, 1375, 0, 1291, - 1295, 1434, 1418, 1324, 276, 0, 0, 0, 0, 0, - 0, 0, 1351, 1362, 1396, 1400, 1345, 0, 0, 0, - 0, 0, 0, 0, 0, 1322, 0, 1371, 0, 0, - 0, 1300, 1292, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1349, 0, 0, 0, 0, - 1303, 0, 1323, 1397, 0, 1286, 298, 1297, 403, 258, - 0, 454, 1404, 1417, 1346, 630, 1419, 1344, 1343, 1391, - 1301, 1410, 1336, 366, 1299, 331, 197, 225, 0, 1334, - 413, 462, 474, 1409, 1319, 1328, 254, 1326, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 1370, 1389, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 1298, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 1314, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 1405, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 1394, 1437, 426, 473, 240, 607, - 497, 199, 1308, 1313, 1306, 0, 255, 256, 1376, 576, - 1309, 1307, 1365, 1366, 1310, 1428, 1429, 1430, 1415, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 1398, 1302, 0, - 1311, 1312, 399, 1407, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 1369, 196, 221, 369, 1433, 455, 289, - 651, 619, 485, 614, 206, 223, 1305, 263, 1317, 1325, - 0, 1331, 1339, 1340, 1353, 1356, 1357, 1358, 1359, 1377, - 1378, 1380, 1388, 1390, 1393, 1395, 1402, 1416, 1436, 198, - 200, 209, 222, 232, 236, 243, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 1368, 1374, 382, - 282, 306, 321, 1383, 618, 503, 227, 467, 291, 251, - 1401, 1403, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 1364, 1392, 377, 577, - 578, 317, 397, 0, 0, 0, 0, 0, 0, 0, - 0, 529, 0, 778, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 765, 0, 0, - 0, 271, 770, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 777, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 772, 773, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 95, 0, 0, 1024, 508, 960, 749, - 926, 964, 1025, 977, 978, 979, 965, 0, 238, 966, - 967, 245, 968, 0, 925, 808, 810, 809, 875, 876, - 877, 878, 879, 880, 881, 811, 812, 806, 973, 610, - 980, 981, 0, 266, 322, 273, 265, 581, 0, 0, - 2233, 2234, 2235, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 745, 762, 0, 776, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 759, - 760, 0, 0, 0, 0, 920, 0, 761, 0, 0, - 769, 982, 983, 984, 985, 986, 987, 988, 989, 990, + 0, 0, 0, 0, 1358, 0, 0, 0, 0, 1312, + 0, 1332, 1406, 0, 1295, 300, 1306, 406, 260, 0, + 459, 1413, 1426, 1355, 636, 1428, 1353, 1352, 1400, 1310, + 1419, 1345, 368, 1308, 333, 199, 227, 0, 1343, 416, + 467, 479, 1418, 1328, 1337, 256, 1335, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 1379, 1398, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 1307, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 1323, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 1414, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 1403, 1446, 429, 478, 242, 613, 502, + 201, 1317, 1322, 1315, 0, 257, 258, 1385, 581, 1318, + 1316, 1374, 1375, 1319, 1437, 1438, 1439, 1424, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 1407, 1311, 0, 1320, + 1321, 402, 1416, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 1378, 198, 223, 371, 1442, 460, 291, 657, + 625, 490, 620, 208, 225, 1314, 265, 1326, 1334, 0, + 1340, 1348, 1349, 1362, 1365, 1366, 1367, 1368, 1386, 1387, + 1389, 1397, 1399, 1402, 1404, 1411, 1425, 1445, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 1377, 1383, 384, 284, 308, 323, 1392, 624, 508, 229, + 472, 293, 253, 1410, 1412, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 1373, + 1401, 379, 582, 583, 319, 400, 0, 0, 0, 0, + 0, 0, 1431, 1415, 534, 0, 1357, 1434, 1325, 1344, + 1444, 1347, 1350, 1394, 1303, 1372, 420, 1341, 1329, 1298, + 1336, 1299, 1327, 1359, 273, 1324, 1417, 1376, 1433, 369, + 270, 1305, 1296, 206, 511, 1330, 435, 1346, 205, 1396, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 1440, 373, 1382, 0, 503, 405, + 0, 0, 0, 1421, 1420, 1351, 1361, 1423, 1370, 1408, + 1356, 1395, 1313, 1381, 1435, 1342, 1391, 1436, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 0, + 513, 196, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 1338, 1388, 616, 1430, 1339, 1390, 268, 324, 275, 267, + 587, 1441, 1422, 1302, 1369, 1429, 1364, 603, 0, 0, + 231, 1432, 1363, 0, 1393, 0, 1447, 1297, 1384, 0, + 1300, 1304, 1443, 1427, 1333, 278, 0, 0, 0, 0, + 0, 0, 0, 1360, 1371, 1405, 1409, 1354, 0, 0, + 0, 0, 0, 0, 3276, 0, 1331, 0, 1380, 0, + 0, 0, 1309, 1301, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1358, 0, 0, 0, + 0, 1312, 0, 1332, 1406, 0, 1295, 300, 1306, 406, + 260, 0, 459, 1413, 1426, 1355, 636, 1428, 1353, 1352, + 1400, 1310, 1419, 1345, 368, 1308, 333, 199, 227, 0, + 1343, 416, 467, 479, 1418, 1328, 1337, 256, 1335, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 1379, + 1398, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 1307, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 1323, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 1414, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 1403, 1446, 429, 478, 242, + 613, 502, 201, 1317, 1322, 1315, 0, 257, 258, 1385, + 581, 1318, 1316, 1374, 1375, 1319, 1437, 1438, 1439, 1424, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 1407, 1311, + 0, 1320, 1321, 402, 1416, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 1378, 198, 223, 371, 1442, 460, + 291, 657, 625, 490, 620, 208, 225, 1314, 265, 1326, + 1334, 0, 1340, 1348, 1349, 1362, 1365, 1366, 1367, 1368, + 1386, 1387, 1389, 1397, 1399, 1402, 1404, 1411, 1425, 1445, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 1377, 1383, 384, 284, 308, 323, 1392, 624, + 508, 229, 472, 293, 253, 1410, 1412, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 1373, 1401, 379, 582, 583, 319, 400, 0, 0, + 0, 0, 0, 0, 1431, 1415, 534, 0, 1357, 1434, + 1325, 1344, 1444, 1347, 1350, 1394, 1303, 1372, 420, 1341, + 1329, 1298, 1336, 1299, 1327, 1359, 273, 1324, 1417, 1376, + 1433, 369, 270, 1305, 1296, 206, 511, 1330, 435, 1346, + 205, 1396, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 1440, 373, 1382, 0, + 503, 405, 0, 0, 0, 1421, 1420, 1351, 1361, 1423, + 1370, 1408, 1356, 1395, 1313, 1381, 1435, 1342, 1391, 1436, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 731, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 1338, 1388, 616, 1430, 1339, 1390, 268, 324, + 275, 267, 587, 1441, 1422, 1302, 1369, 1429, 1364, 603, + 0, 0, 231, 1432, 1363, 0, 1393, 0, 1447, 1297, + 1384, 0, 1300, 1304, 1443, 1427, 1333, 278, 0, 0, + 0, 0, 0, 0, 0, 1360, 1371, 1405, 1409, 1354, + 0, 0, 0, 0, 0, 0, 3237, 0, 1331, 0, + 1380, 0, 0, 0, 1309, 1301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1358, 0, + 0, 0, 0, 1312, 0, 1332, 1406, 0, 1295, 300, + 1306, 406, 260, 0, 459, 1413, 1426, 1355, 636, 1428, + 1353, 1352, 1400, 1310, 1419, 1345, 368, 1308, 333, 199, + 227, 0, 1343, 416, 467, 479, 1418, 1328, 1337, 256, + 1335, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 1379, 1398, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 1307, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 1323, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 1414, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 1403, 1446, 429, + 478, 242, 613, 502, 201, 1317, 1322, 1315, 0, 257, + 258, 1385, 581, 1318, 1316, 1374, 1375, 1319, 1437, 1438, + 1439, 1424, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 1407, 1311, 0, 1320, 1321, 402, 1416, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 1378, 198, 223, 371, + 1442, 460, 291, 657, 625, 490, 620, 208, 225, 1314, + 265, 1326, 1334, 0, 1340, 1348, 1349, 1362, 1365, 1366, + 1367, 1368, 1386, 1387, 1389, 1397, 1399, 1402, 1404, 1411, + 1425, 1445, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 1377, 1383, 384, 284, 308, 323, + 1392, 624, 508, 229, 472, 293, 253, 1410, 1412, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 1373, 1401, 379, 582, 583, 319, 400, + 0, 0, 0, 0, 0, 0, 1431, 1415, 534, 0, + 1357, 1434, 1325, 1344, 1444, 1347, 1350, 1394, 1303, 1372, + 420, 1341, 1329, 1298, 1336, 1299, 1327, 1359, 273, 1324, + 1417, 1376, 1433, 369, 270, 1305, 1296, 206, 511, 1330, + 435, 1346, 205, 1396, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 1440, 373, + 1382, 0, 503, 405, 0, 0, 0, 1421, 1420, 1351, + 1361, 1423, 1370, 1408, 1356, 1395, 1313, 1381, 1435, 1342, + 1391, 1436, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 0, 513, 966, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 1338, 1388, 616, 1430, 1339, 1390, + 268, 324, 275, 267, 587, 1441, 1422, 1302, 1369, 1429, + 1364, 603, 0, 0, 231, 1432, 1363, 0, 1393, 0, + 1447, 1297, 1384, 0, 1300, 1304, 1443, 1427, 1333, 278, + 0, 0, 0, 0, 0, 0, 0, 1360, 1371, 1405, + 1409, 1354, 0, 0, 0, 0, 0, 0, 2428, 0, + 1331, 0, 1380, 0, 0, 0, 1309, 1301, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1358, 0, 0, 0, 0, 1312, 0, 1332, 1406, 0, + 1295, 300, 1306, 406, 260, 0, 459, 1413, 1426, 1355, + 636, 1428, 1353, 1352, 1400, 1310, 1419, 1345, 368, 1308, + 333, 199, 227, 0, 1343, 416, 467, 479, 1418, 1328, + 1337, 256, 1335, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 1379, 1398, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 1307, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 1323, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 1414, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 1403, + 1446, 429, 478, 242, 613, 502, 201, 1317, 1322, 1315, + 0, 257, 258, 1385, 581, 1318, 1316, 1374, 1375, 1319, + 1437, 1438, 1439, 1424, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 1407, 1311, 0, 1320, 1321, 402, 1416, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 1378, 198, + 223, 371, 1442, 460, 291, 657, 625, 490, 620, 208, + 225, 1314, 265, 1326, 1334, 0, 1340, 1348, 1349, 1362, + 1365, 1366, 1367, 1368, 1386, 1387, 1389, 1397, 1399, 1402, + 1404, 1411, 1425, 1445, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 1377, 1383, 384, 284, + 308, 323, 1392, 624, 508, 229, 472, 293, 253, 1410, + 1412, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 1373, 1401, 379, 582, 583, + 319, 400, 0, 0, 0, 0, 0, 0, 1431, 1415, + 534, 0, 1357, 1434, 1325, 1344, 1444, 1347, 1350, 1394, + 1303, 1372, 420, 1341, 1329, 1298, 1336, 1299, 1327, 1359, + 273, 1324, 1417, 1376, 1433, 369, 270, 1305, 1296, 206, + 511, 1330, 435, 1346, 205, 1396, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 1440, 373, 1382, 0, 503, 405, 0, 0, 0, 1421, + 1420, 1351, 1361, 1423, 1370, 1408, 1356, 1395, 1313, 1381, + 1435, 1342, 1391, 1436, 326, 250, 328, 204, 417, 504, + 289, 0, 95, 0, 0, 0, 513, 731, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 1338, 1388, 616, 1430, + 1339, 1390, 268, 324, 275, 267, 587, 1441, 1422, 1302, + 1369, 1429, 1364, 603, 0, 0, 231, 1432, 1363, 0, + 1393, 0, 1447, 1297, 1384, 0, 1300, 1304, 1443, 1427, + 1333, 278, 0, 0, 0, 0, 0, 0, 0, 1360, + 1371, 1405, 1409, 1354, 0, 0, 0, 0, 0, 0, + 0, 0, 1331, 0, 1380, 0, 0, 0, 1309, 1301, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1358, 0, 0, 0, 0, 1312, 0, 1332, + 1406, 0, 1295, 300, 1306, 406, 260, 0, 459, 1413, + 1426, 1355, 636, 1428, 1353, 1352, 1400, 1310, 1419, 1345, + 368, 1308, 333, 199, 227, 0, 1343, 416, 467, 479, + 1418, 1328, 1337, 256, 1335, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 1379, 1398, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 1307, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 1323, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 1414, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 1403, 1446, 429, 478, 242, 613, 502, 201, 1317, + 1322, 1315, 0, 257, 258, 1385, 581, 1318, 1316, 1374, + 1375, 1319, 1437, 1438, 1439, 1424, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 1407, 1311, 0, 1320, 1321, 402, + 1416, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 1378, 198, 223, 371, 1442, 460, 291, 657, 625, 490, + 620, 208, 225, 1314, 265, 1326, 1334, 0, 1340, 1348, + 1349, 1362, 1365, 1366, 1367, 1368, 1386, 1387, 1389, 1397, + 1399, 1402, 1404, 1411, 1425, 1445, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 1377, 1383, + 384, 284, 308, 323, 1392, 624, 508, 229, 472, 293, + 253, 1410, 1412, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 1373, 1401, 379, + 582, 583, 319, 400, 0, 0, 0, 0, 0, 0, + 1431, 1415, 534, 0, 1357, 1434, 1325, 1344, 1444, 1347, + 1350, 1394, 1303, 1372, 420, 1341, 1329, 1298, 1336, 1299, + 1327, 1359, 273, 1324, 1417, 1376, 1433, 369, 270, 1305, + 1296, 206, 511, 1330, 435, 1346, 205, 1396, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 1440, 373, 1382, 0, 503, 405, 0, 0, + 0, 1421, 1420, 1351, 1361, 1423, 1370, 1408, 1356, 1395, + 1313, 1381, 1435, 1342, 1391, 1436, 326, 250, 328, 204, + 417, 504, 289, 0, 0, 0, 0, 0, 513, 196, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 1338, 1388, + 616, 1430, 1339, 1390, 268, 324, 275, 267, 587, 1441, + 1422, 1302, 1369, 1429, 1364, 603, 0, 0, 231, 1432, + 1363, 0, 1393, 0, 1447, 1297, 1384, 0, 1300, 1304, + 1443, 1427, 1333, 278, 0, 0, 0, 0, 0, 0, + 0, 1360, 1371, 1405, 1409, 1354, 0, 0, 0, 0, + 0, 0, 0, 0, 1331, 0, 1380, 0, 0, 0, + 1309, 1301, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1358, 0, 0, 0, 0, 1312, + 0, 1332, 1406, 0, 1295, 300, 1306, 406, 260, 0, + 459, 1413, 1426, 1355, 636, 1428, 1353, 1352, 1400, 1310, + 1419, 1345, 368, 1308, 333, 199, 227, 0, 1343, 416, + 467, 479, 1418, 1328, 1337, 256, 1335, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 1379, 1398, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 1307, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 1323, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 1414, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 1403, 1446, 429, 478, 242, 613, 502, + 201, 1317, 1322, 1315, 0, 257, 258, 1385, 581, 1318, + 1316, 1374, 1375, 1319, 1437, 1438, 1439, 1424, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 1407, 1311, 0, 1320, + 1321, 402, 1416, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 1378, 198, 223, 371, 1442, 460, 291, 657, + 625, 490, 620, 208, 225, 1314, 265, 1326, 1334, 0, + 1340, 1348, 1349, 1362, 1365, 1366, 1367, 1368, 1386, 1387, + 1389, 1397, 1399, 1402, 1404, 1411, 1425, 1445, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 1377, 1383, 384, 284, 308, 323, 1392, 624, 508, 229, + 472, 293, 253, 1410, 1412, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 1373, + 1401, 379, 582, 583, 319, 400, 0, 0, 0, 0, + 0, 0, 1431, 1415, 534, 0, 1357, 1434, 1325, 1344, + 1444, 1347, 1350, 1394, 1303, 1372, 420, 1341, 1329, 1298, + 1336, 1299, 1327, 1359, 273, 1324, 1417, 1376, 1433, 369, + 270, 1305, 1296, 206, 511, 1330, 435, 1346, 205, 1396, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 1440, 373, 1382, 0, 503, 405, + 0, 0, 0, 1421, 1420, 1351, 1361, 1423, 1370, 1408, + 1356, 1395, 1313, 1381, 1435, 1342, 1391, 1436, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 0, + 513, 731, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 1338, 1388, 616, 1430, 1339, 1390, 268, 324, 275, 267, + 587, 1441, 1422, 1302, 1369, 1429, 1364, 603, 0, 0, + 231, 1432, 1363, 0, 1393, 0, 1447, 1297, 1384, 0, + 1300, 1304, 1443, 1427, 1333, 278, 0, 0, 0, 0, + 0, 0, 0, 1360, 1371, 1405, 1409, 1354, 0, 0, + 0, 0, 0, 0, 0, 0, 1331, 0, 1380, 0, + 0, 0, 1309, 1301, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1358, 0, 0, 0, + 0, 1312, 0, 1332, 1406, 0, 1295, 300, 1306, 406, + 260, 0, 459, 1413, 1426, 1355, 636, 1428, 1353, 1352, + 1400, 1310, 1419, 1345, 368, 1308, 333, 199, 227, 0, + 1343, 416, 467, 479, 1418, 1328, 1337, 256, 1335, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 1379, + 1398, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 1307, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 1323, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 1414, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 1403, 1446, 429, 478, 242, + 613, 502, 201, 1317, 1322, 1315, 0, 257, 258, 1385, + 581, 1318, 1316, 1374, 1375, 1319, 1437, 1438, 1439, 1424, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 1407, 1311, + 0, 1320, 1321, 402, 1416, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 1378, 198, 223, 371, 1442, 460, + 291, 657, 625, 490, 620, 208, 225, 1314, 265, 1326, + 1334, 0, 1340, 1348, 1349, 1362, 1365, 1366, 1367, 1368, + 1386, 1387, 1389, 1397, 1399, 1402, 1404, 1411, 1425, 1445, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 1377, 1383, 384, 284, 308, 323, 1392, 624, + 508, 229, 472, 293, 253, 1410, 1412, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 1373, 1401, 379, 582, 583, 319, 400, 0, 0, + 0, 0, 0, 0, 1431, 1415, 534, 0, 1357, 1434, + 1325, 1344, 1444, 1347, 1350, 1394, 1303, 1372, 420, 1341, + 1329, 1298, 1336, 1299, 1327, 1359, 273, 1324, 1417, 1376, + 1433, 369, 270, 1305, 1296, 206, 511, 1330, 435, 1346, + 205, 1396, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 1440, 373, 1382, 0, + 503, 405, 0, 0, 0, 1421, 1420, 1351, 1361, 1423, + 1370, 1408, 1356, 1395, 1313, 1381, 1435, 1342, 1391, 1436, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 966, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 1338, 1388, 616, 1430, 1339, 1390, 268, 324, + 275, 267, 587, 1441, 1422, 1302, 1369, 1429, 1364, 603, + 0, 0, 231, 1432, 1363, 0, 1393, 0, 1447, 1297, + 1384, 0, 1300, 1304, 1443, 1427, 1333, 278, 0, 0, + 0, 0, 0, 0, 0, 1360, 1371, 1405, 1409, 1354, + 0, 0, 0, 0, 0, 0, 0, 0, 1331, 0, + 1380, 0, 0, 0, 1309, 1301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1358, 0, + 0, 0, 0, 1312, 0, 1332, 1406, 0, 1295, 300, + 1306, 406, 260, 0, 459, 1413, 1426, 1355, 636, 1428, + 1353, 1352, 1400, 1310, 1419, 1345, 368, 1308, 333, 199, + 227, 0, 1343, 416, 467, 479, 1418, 1328, 1337, 256, + 1335, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 1379, 1398, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 1307, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 1323, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 1414, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 1403, 1446, 429, + 478, 242, 613, 502, 201, 1317, 1322, 1315, 0, 257, + 258, 1385, 581, 1318, 1316, 1374, 1375, 1319, 1437, 1438, + 1439, 1424, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 1407, 1311, 0, 1320, 1321, 402, 1416, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 1378, 198, 223, 371, + 1442, 460, 291, 657, 625, 490, 620, 208, 225, 1314, + 265, 1326, 1334, 0, 1340, 1348, 1349, 1362, 1365, 1366, + 1367, 1368, 1386, 1387, 1389, 1397, 1399, 1402, 1404, 1411, + 1425, 1445, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 1377, 1383, 384, 284, 308, 323, + 1392, 624, 508, 229, 472, 293, 253, 1410, 1412, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 1373, 1401, 379, 582, 583, 319, 400, + 0, 0, 0, 0, 0, 0, 0, 0, 534, 0, + 784, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 771, 0, 0, 0, 273, 776, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 783, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 778, 779, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 95, 0, 0, 1032, 513, 966, 755, 932, 970, 1033, + 984, 985, 986, 971, 0, 240, 972, 973, 247, 974, + 0, 931, 814, 816, 815, 881, 882, 883, 884, 885, + 886, 887, 817, 818, 812, 979, 616, 987, 988, 0, + 268, 324, 275, 267, 587, 0, 0, 2248, 2249, 2250, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 751, 768, 0, 782, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 765, 766, 0, 0, + 0, 0, 926, 0, 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, - 1021, 1022, 1023, 771, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 919, 0, 0, 630, 0, 0, 917, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 970, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 971, 972, 257, 653, 816, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 824, 825, 281, 308, 901, 900, - 899, 307, 309, 897, 898, 896, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 907, - 929, 918, 782, 783, 908, 909, 933, 910, 785, 786, - 930, 931, 779, 780, 784, 932, 934, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 921, 768, 767, 0, 774, - 775, 0, 804, 805, 807, 813, 814, 815, 826, 873, - 874, 882, 884, 885, 883, 886, 887, 888, 891, 892, - 893, 894, 889, 890, 895, 787, 791, 788, 789, 790, - 802, 792, 793, 794, 795, 796, 797, 798, 799, 800, - 801, 803, 944, 945, 946, 947, 948, 949, 819, 823, - 822, 820, 821, 817, 818, 845, 844, 846, 847, 848, - 849, 850, 851, 853, 852, 854, 855, 856, 857, 858, - 859, 827, 828, 831, 832, 830, 829, 833, 842, 843, - 834, 835, 836, 837, 838, 839, 841, 840, 860, 861, - 862, 863, 864, 866, 865, 869, 870, 868, 867, 872, - 871, 766, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 935, 263, 936, 0, 0, 940, - 0, 0, 0, 942, 941, 0, 943, 905, 904, 0, - 0, 937, 938, 0, 939, 0, 0, 198, 200, 209, - 222, 232, 236, 243, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 950, - 951, 952, 953, 954, 955, 956, 957, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 975, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 778, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 765, - 0, 0, 0, 271, 770, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 777, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 772, 773, 0, - 0, 0, 0, 0, 0, 2440, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 95, 0, 0, 1024, 508, - 960, 749, 926, 964, 1025, 977, 978, 979, 965, 0, - 238, 966, 967, 245, 968, 0, 925, 808, 810, 809, - 875, 876, 877, 878, 879, 880, 881, 811, 812, 806, - 973, 610, 980, 981, 2441, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 745, 762, 0, - 776, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 759, 760, 0, 0, 0, 0, 920, 0, 761, - 0, 0, 769, 982, 983, 984, 985, 986, 987, 988, + 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, + 777, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 925, 0, 0, + 636, 0, 0, 923, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 976, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 977, 978, 259, 659, 822, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 830, 831, 283, 310, 907, 906, 905, 309, 311, + 903, 904, 902, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 913, 935, 924, 788, + 789, 914, 915, 939, 916, 791, 792, 936, 937, 785, + 786, 790, 938, 940, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 927, 774, 773, 0, 780, 781, 0, 810, + 811, 813, 819, 820, 821, 832, 879, 880, 888, 890, + 891, 889, 892, 893, 894, 897, 898, 899, 900, 895, + 896, 901, 793, 797, 794, 795, 796, 808, 798, 799, + 800, 801, 802, 803, 804, 805, 806, 807, 809, 950, + 951, 952, 953, 954, 955, 825, 829, 828, 826, 827, + 823, 824, 851, 850, 852, 853, 854, 855, 856, 857, + 859, 858, 860, 861, 862, 863, 864, 865, 833, 834, + 837, 838, 836, 835, 839, 848, 849, 840, 841, 842, + 843, 844, 845, 847, 846, 866, 867, 868, 869, 870, + 872, 871, 875, 876, 874, 873, 878, 877, 772, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 941, 265, 942, 0, 0, 946, 0, 0, 0, + 948, 947, 0, 949, 911, 910, 0, 0, 943, 944, + 0, 945, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 956, 957, 958, 959, 960, 961, 962, 963, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 1031, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 784, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 771, 0, 0, 0, 273, 776, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 783, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 778, 779, + 0, 0, 0, 0, 0, 0, 2457, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 95, 0, 0, 1032, + 513, 966, 755, 932, 970, 1033, 984, 985, 986, 971, + 0, 240, 972, 973, 247, 974, 0, 931, 814, 816, + 815, 881, 882, 883, 884, 885, 886, 887, 817, 818, + 812, 979, 616, 987, 988, 2458, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 751, 768, + 0, 782, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 765, 766, 0, 0, 0, 0, 926, 0, + 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, + 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, + 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, + 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, + 1025, 1026, 1027, 1028, 1029, 1030, 777, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 925, 0, 0, 636, 0, 0, 923, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 976, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 977, 978, + 259, 659, 822, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 830, 831, 283, + 310, 907, 906, 905, 309, 311, 903, 904, 902, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 913, 935, 924, 788, 789, 914, 915, 939, + 916, 791, 792, 936, 937, 785, 786, 790, 938, 940, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 927, 774, + 773, 0, 780, 781, 0, 810, 811, 813, 819, 820, + 821, 832, 879, 880, 888, 890, 891, 889, 892, 893, + 894, 897, 898, 899, 900, 895, 896, 901, 793, 797, + 794, 795, 796, 808, 798, 799, 800, 801, 802, 803, + 804, 805, 806, 807, 809, 950, 951, 952, 953, 954, + 955, 825, 829, 828, 826, 827, 823, 824, 851, 850, + 852, 853, 854, 855, 856, 857, 859, 858, 860, 861, + 862, 863, 864, 865, 833, 834, 837, 838, 836, 835, + 839, 848, 849, 840, 841, 842, 843, 844, 845, 847, + 846, 866, 867, 868, 869, 870, 872, 871, 875, 876, + 874, 873, 878, 877, 772, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 941, 265, 942, + 0, 0, 946, 0, 0, 0, 948, 947, 0, 949, + 911, 910, 0, 0, 943, 944, 0, 945, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 956, 957, 958, 959, + 960, 961, 962, 963, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 1031, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 86, + 534, 0, 784, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 771, 0, 0, 0, + 273, 776, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 1727, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 778, 779, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 95, 0, 0, 1032, 513, 966, 755, 932, + 970, 1033, 984, 985, 986, 971, 0, 240, 972, 973, + 247, 974, 0, 931, 814, 816, 815, 881, 882, 883, + 884, 885, 886, 887, 817, 818, 812, 979, 616, 987, + 988, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 751, 768, 0, 782, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 765, 766, + 0, 0, 0, 0, 926, 0, 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, - 1019, 1020, 1021, 1022, 1023, 771, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 919, 0, 0, 630, 0, 0, 917, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 970, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 971, 972, 257, - 653, 816, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 824, 825, 281, 308, - 901, 900, 899, 307, 309, 897, 898, 896, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 907, 929, 918, 782, 783, 908, 909, 933, 910, - 785, 786, 930, 931, 779, 780, 784, 932, 934, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 921, 768, 767, - 0, 774, 775, 0, 804, 805, 807, 813, 814, 815, - 826, 873, 874, 882, 884, 885, 883, 886, 887, 888, - 891, 892, 893, 894, 889, 890, 895, 787, 791, 788, - 789, 790, 802, 792, 793, 794, 795, 796, 797, 798, - 799, 800, 801, 803, 944, 945, 946, 947, 948, 949, - 819, 823, 822, 820, 821, 817, 818, 845, 844, 846, - 847, 848, 849, 850, 851, 853, 852, 854, 855, 856, - 857, 858, 859, 827, 828, 831, 832, 830, 829, 833, - 842, 843, 834, 835, 836, 837, 838, 839, 841, 840, - 860, 861, 862, 863, 864, 866, 865, 869, 870, 868, - 867, 872, 871, 766, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 935, 263, 936, 0, - 0, 940, 0, 0, 0, 942, 941, 0, 943, 905, - 904, 0, 0, 937, 938, 0, 939, 0, 0, 198, - 200, 209, 222, 232, 236, 243, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 950, 951, 952, 953, 954, 955, 956, 957, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 975, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 86, 529, 0, 778, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 765, 0, 0, 0, 271, 770, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 777, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 772, - 773, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 95, 0, 0, - 1024, 508, 960, 749, 926, 964, 1025, 977, 978, 979, - 965, 0, 238, 966, 967, 245, 968, 0, 925, 808, - 810, 809, 875, 876, 877, 878, 879, 880, 881, 811, - 812, 806, 973, 610, 980, 981, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 745, - 762, 0, 776, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 759, 760, 0, 0, 0, 0, 920, - 0, 761, 0, 0, 769, 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, 1012, 1013, 1014, 1015, 1016, - 1017, 1018, 1019, 1020, 1021, 1022, 1023, 771, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 919, 0, 0, 630, 0, 0, - 917, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 970, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 971, - 972, 257, 653, 816, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 824, 825, - 281, 308, 901, 900, 899, 307, 309, 897, 898, 896, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 907, 929, 918, 782, 783, 908, 909, - 933, 910, 785, 786, 930, 931, 779, 780, 784, 932, - 934, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 921, - 768, 767, 0, 774, 775, 0, 804, 805, 807, 813, - 814, 815, 826, 873, 874, 882, 884, 885, 883, 886, - 887, 888, 891, 892, 893, 894, 889, 890, 895, 787, - 791, 788, 789, 790, 802, 792, 793, 794, 795, 796, - 797, 798, 799, 800, 801, 803, 944, 945, 946, 947, - 948, 949, 819, 823, 822, 820, 821, 817, 818, 845, - 844, 846, 847, 848, 849, 850, 851, 853, 852, 854, - 855, 856, 857, 858, 859, 827, 828, 831, 832, 830, - 829, 833, 842, 843, 834, 835, 836, 837, 838, 839, - 841, 840, 860, 861, 862, 863, 864, 866, 865, 869, - 870, 868, 867, 872, 871, 766, 196, 221, 369, 94, - 455, 289, 651, 619, 485, 614, 206, 223, 935, 263, - 936, 0, 0, 940, 0, 0, 0, 942, 941, 0, - 943, 905, 904, 0, 0, 937, 938, 0, 939, 0, - 0, 198, 200, 209, 222, 232, 236, 243, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 950, 951, 952, 953, 954, 955, 956, - 957, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 975, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 778, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 765, 0, 0, 0, 271, 770, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 777, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 772, 773, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 95, - 0, 0, 1024, 508, 960, 749, 926, 964, 1025, 977, - 978, 979, 965, 0, 238, 966, 967, 245, 968, 0, - 925, 808, 810, 809, 875, 876, 877, 878, 879, 880, - 881, 811, 812, 806, 973, 610, 980, 981, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 745, 762, 0, 776, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 759, 760, 0, 0, 0, - 0, 920, 0, 761, 0, 0, 769, 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, 1012, 1013, 1014, - 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 771, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 919, 0, 0, 630, - 0, 0, 917, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 970, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 4098, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 971, 972, 257, 653, 816, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 824, 825, 281, 308, 901, 900, 899, 307, 309, 897, - 898, 896, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 907, 929, 918, 782, 783, - 908, 909, 933, 910, 785, 786, 930, 931, 779, 780, - 784, 932, 934, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 921, 768, 767, 0, 774, 775, 0, 804, 805, - 807, 813, 814, 815, 826, 873, 874, 882, 884, 885, - 883, 886, 887, 888, 891, 892, 893, 894, 889, 890, - 895, 787, 791, 788, 789, 790, 802, 792, 793, 794, - 795, 796, 797, 798, 799, 800, 801, 803, 944, 945, - 946, 947, 948, 949, 819, 823, 822, 820, 821, 817, - 818, 845, 844, 846, 847, 848, 849, 850, 851, 853, - 852, 854, 855, 856, 857, 858, 859, 827, 828, 831, - 832, 830, 829, 833, 842, 843, 834, 835, 836, 837, - 838, 839, 841, 840, 860, 861, 862, 863, 864, 866, - 865, 869, 870, 868, 867, 872, 871, 766, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 935, 263, 936, 0, 0, 940, 0, 0, 0, 942, - 941, 0, 943, 905, 904, 0, 0, 937, 938, 0, - 939, 0, 0, 198, 200, 209, 222, 232, 236, 243, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 950, 951, 952, 953, 954, - 955, 956, 957, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 975, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 778, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 765, 0, 0, 0, 271, - 770, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 777, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 772, 773, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 95, 0, 1754, 1024, 508, 960, 749, 926, 964, - 1025, 977, 978, 979, 965, 0, 238, 966, 967, 245, - 968, 0, 925, 808, 810, 809, 875, 876, 877, 878, - 879, 880, 881, 811, 812, 806, 973, 610, 980, 981, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 745, 762, 0, 776, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 759, 760, 0, - 0, 0, 0, 920, 0, 761, 0, 0, 769, 982, - 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 777, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 925, + 0, 0, 636, 0, 0, 923, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 976, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 977, 978, 259, 659, 822, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 830, 831, 283, 310, 907, 906, 905, + 309, 311, 903, 904, 902, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 913, 935, + 924, 788, 789, 914, 915, 939, 916, 791, 792, 936, + 937, 785, 786, 790, 938, 940, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 927, 774, 773, 0, 780, 781, + 0, 810, 811, 813, 819, 820, 821, 832, 879, 880, + 888, 890, 891, 889, 892, 893, 894, 897, 898, 899, + 900, 895, 896, 901, 793, 797, 794, 795, 796, 808, + 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, + 809, 950, 951, 952, 953, 954, 955, 825, 829, 828, + 826, 827, 823, 824, 851, 850, 852, 853, 854, 855, + 856, 857, 859, 858, 860, 861, 862, 863, 864, 865, + 833, 834, 837, 838, 836, 835, 839, 848, 849, 840, + 841, 842, 843, 844, 845, 847, 846, 866, 867, 868, + 869, 870, 872, 871, 875, 876, 874, 873, 878, 877, + 772, 198, 223, 371, 94, 460, 291, 657, 625, 490, + 620, 208, 225, 941, 265, 942, 0, 0, 946, 0, + 0, 0, 948, 947, 0, 949, 911, 910, 0, 0, + 943, 944, 0, 945, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 956, 957, 958, 959, 960, 961, 962, 963, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 1031, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 784, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 771, 0, 0, 0, 273, 776, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 783, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 778, 779, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 95, 0, + 0, 1032, 513, 966, 755, 932, 970, 1033, 984, 985, + 986, 971, 0, 240, 972, 973, 247, 974, 0, 931, + 814, 816, 815, 881, 882, 883, 884, 885, 886, 887, + 817, 818, 812, 979, 616, 987, 988, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 751, 768, 0, 782, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 765, 766, 0, 0, 0, 0, + 926, 0, 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 771, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 919, 0, - 0, 630, 0, 0, 917, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 970, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 971, 972, 257, 653, 816, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 824, 825, 281, 308, 901, 900, 899, 307, - 309, 897, 898, 896, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 907, 929, 918, - 782, 783, 908, 909, 933, 910, 785, 786, 930, 931, - 779, 780, 784, 932, 934, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 921, 768, 767, 0, 774, 775, 0, - 804, 805, 807, 813, 814, 815, 826, 873, 874, 882, - 884, 885, 883, 886, 887, 888, 891, 892, 893, 894, - 889, 890, 895, 787, 791, 788, 789, 790, 802, 792, - 793, 794, 795, 796, 797, 798, 799, 800, 801, 803, - 944, 945, 946, 947, 948, 949, 819, 823, 822, 820, - 821, 817, 818, 845, 844, 846, 847, 848, 849, 850, - 851, 853, 852, 854, 855, 856, 857, 858, 859, 827, - 828, 831, 832, 830, 829, 833, 842, 843, 834, 835, - 836, 837, 838, 839, 841, 840, 860, 861, 862, 863, - 864, 866, 865, 869, 870, 868, 867, 872, 871, 766, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 935, 263, 936, 0, 0, 940, 0, 0, - 0, 942, 941, 0, 943, 905, 904, 0, 0, 937, - 938, 0, 939, 0, 0, 198, 200, 209, 222, 232, - 236, 243, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 950, 951, 952, - 953, 954, 955, 956, 957, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 975, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 778, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 765, 0, 0, - 0, 271, 770, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 777, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 772, 773, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 95, 0, 0, 1024, 508, 960, 749, - 926, 964, 1025, 977, 978, 979, 965, 0, 238, 966, - 967, 245, 968, 0, 925, 808, 810, 809, 875, 876, - 877, 878, 879, 880, 881, 811, 812, 806, 973, 610, - 980, 981, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 745, 762, 0, 776, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 759, - 760, 1070, 0, 0, 0, 920, 0, 761, 0, 0, - 769, 982, 983, 984, 985, 986, 987, 988, 989, 990, + 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 777, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 925, 0, 0, 636, 0, + 0, 923, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 976, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 4117, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 977, 978, 259, 659, 822, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 830, + 831, 283, 310, 907, 906, 905, 309, 311, 903, 904, + 902, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 913, 935, 924, 788, 789, 914, + 915, 939, 916, 791, 792, 936, 937, 785, 786, 790, + 938, 940, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 927, 774, 773, 0, 780, 781, 0, 810, 811, 813, + 819, 820, 821, 832, 879, 880, 888, 890, 891, 889, + 892, 893, 894, 897, 898, 899, 900, 895, 896, 901, + 793, 797, 794, 795, 796, 808, 798, 799, 800, 801, + 802, 803, 804, 805, 806, 807, 809, 950, 951, 952, + 953, 954, 955, 825, 829, 828, 826, 827, 823, 824, + 851, 850, 852, 853, 854, 855, 856, 857, 859, 858, + 860, 861, 862, 863, 864, 865, 833, 834, 837, 838, + 836, 835, 839, 848, 849, 840, 841, 842, 843, 844, + 845, 847, 846, 866, 867, 868, 869, 870, 872, 871, + 875, 876, 874, 873, 878, 877, 772, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 941, + 265, 942, 0, 0, 946, 0, 0, 0, 948, 947, + 0, 949, 911, 910, 0, 0, 943, 944, 0, 945, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 956, 957, + 958, 959, 960, 961, 962, 963, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 1031, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 784, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 771, 0, + 0, 0, 273, 776, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 783, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 778, 779, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 95, 0, 1764, 1032, 513, 966, + 755, 932, 970, 1033, 984, 985, 986, 971, 0, 240, + 972, 973, 247, 974, 0, 931, 814, 816, 815, 881, + 882, 883, 884, 885, 886, 887, 817, 818, 812, 979, + 616, 987, 988, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 751, 768, 0, 782, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 765, 766, 0, 0, 0, 0, 926, 0, 767, 0, + 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, + 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, + 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, + 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, + 1027, 1028, 1029, 1030, 777, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 925, 0, 0, 636, 0, 0, 923, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 976, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 977, 978, 259, 659, + 822, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 830, 831, 283, 310, 907, + 906, 905, 309, 311, 903, 904, 902, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 913, 935, 924, 788, 789, 914, 915, 939, 916, 791, + 792, 936, 937, 785, 786, 790, 938, 940, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 927, 774, 773, 0, + 780, 781, 0, 810, 811, 813, 819, 820, 821, 832, + 879, 880, 888, 890, 891, 889, 892, 893, 894, 897, + 898, 899, 900, 895, 896, 901, 793, 797, 794, 795, + 796, 808, 798, 799, 800, 801, 802, 803, 804, 805, + 806, 807, 809, 950, 951, 952, 953, 954, 955, 825, + 829, 828, 826, 827, 823, 824, 851, 850, 852, 853, + 854, 855, 856, 857, 859, 858, 860, 861, 862, 863, + 864, 865, 833, 834, 837, 838, 836, 835, 839, 848, + 849, 840, 841, 842, 843, 844, 845, 847, 846, 866, + 867, 868, 869, 870, 872, 871, 875, 876, 874, 873, + 878, 877, 772, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 941, 265, 942, 0, 0, + 946, 0, 0, 0, 948, 947, 0, 949, 911, 910, + 0, 0, 943, 944, 0, 945, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 956, 957, 958, 959, 960, 961, + 962, 963, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 1031, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 784, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 771, 0, 0, 0, 273, 776, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 783, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 778, 779, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 95, 0, 0, 1032, 513, 966, 755, 932, 970, 1033, + 984, 985, 986, 971, 0, 240, 972, 973, 247, 974, + 0, 931, 814, 816, 815, 881, 882, 883, 884, 885, + 886, 887, 817, 818, 812, 979, 616, 987, 988, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 751, 768, 0, 782, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 765, 766, 1079, 0, + 0, 0, 926, 0, 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, - 1021, 1022, 1023, 771, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 919, 0, 0, 630, 0, 0, 917, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 970, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 971, 972, 257, 653, 816, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 824, 825, 281, 308, 901, 900, - 899, 307, 309, 897, 898, 896, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 907, - 929, 918, 782, 783, 908, 909, 933, 910, 785, 786, - 930, 931, 779, 780, 784, 932, 934, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 921, 768, 767, 0, 774, - 775, 0, 804, 805, 807, 813, 814, 815, 826, 873, - 874, 882, 884, 885, 883, 886, 887, 888, 891, 892, - 893, 894, 889, 890, 895, 787, 791, 788, 789, 790, - 802, 792, 793, 794, 795, 796, 797, 798, 799, 800, - 801, 803, 944, 945, 946, 947, 948, 949, 819, 823, - 822, 820, 821, 817, 818, 845, 844, 846, 847, 848, - 849, 850, 851, 853, 852, 854, 855, 856, 857, 858, - 859, 827, 828, 831, 832, 830, 829, 833, 842, 843, - 834, 835, 836, 837, 838, 839, 841, 840, 860, 861, - 862, 863, 864, 866, 865, 869, 870, 868, 867, 872, - 871, 766, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 935, 263, 936, 0, 0, 940, - 0, 0, 0, 942, 941, 0, 943, 905, 904, 0, - 0, 937, 938, 0, 939, 0, 0, 198, 200, 209, - 222, 232, 236, 243, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 950, - 951, 952, 953, 954, 955, 956, 957, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 975, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 778, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 765, - 0, 0, 0, 271, 770, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 777, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 772, 773, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 95, 0, 0, 1024, 508, - 960, 749, 926, 964, 1025, 977, 978, 979, 965, 0, - 238, 966, 967, 245, 968, 0, 925, 808, 810, 809, - 875, 876, 877, 878, 879, 880, 881, 811, 812, 806, - 973, 610, 980, 981, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 745, 762, 0, - 776, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 759, 760, 0, 0, 0, 0, 920, 0, 761, - 0, 0, 769, 982, 983, 984, 985, 986, 987, 988, + 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, + 777, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 925, 0, 0, + 636, 0, 0, 923, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 976, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 977, 978, 259, 659, 822, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 830, 831, 283, 310, 907, 906, 905, 309, 311, + 903, 904, 902, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 913, 935, 924, 788, + 789, 914, 915, 939, 916, 791, 792, 936, 937, 785, + 786, 790, 938, 940, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 927, 774, 773, 0, 780, 781, 0, 810, + 811, 813, 819, 820, 821, 832, 879, 880, 888, 890, + 891, 889, 892, 893, 894, 897, 898, 899, 900, 895, + 896, 901, 793, 797, 794, 795, 796, 808, 798, 799, + 800, 801, 802, 803, 804, 805, 806, 807, 809, 950, + 951, 952, 953, 954, 955, 825, 829, 828, 826, 827, + 823, 824, 851, 850, 852, 853, 854, 855, 856, 857, + 859, 858, 860, 861, 862, 863, 864, 865, 833, 834, + 837, 838, 836, 835, 839, 848, 849, 840, 841, 842, + 843, 844, 845, 847, 846, 866, 867, 868, 869, 870, + 872, 871, 875, 876, 874, 873, 878, 877, 772, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 941, 265, 942, 0, 0, 946, 0, 0, 0, + 948, 947, 0, 949, 911, 910, 0, 0, 943, 944, + 0, 945, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 956, 957, 958, 959, 960, 961, 962, 963, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 1031, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 784, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 771, 0, 0, 0, 273, 776, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 783, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 778, 779, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 95, 0, 0, 1032, + 513, 966, 755, 932, 970, 1033, 984, 985, 986, 971, + 0, 240, 972, 973, 247, 974, 0, 931, 814, 816, + 815, 881, 882, 883, 884, 885, 886, 887, 817, 818, + 812, 979, 616, 987, 988, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 751, 768, + 0, 782, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 765, 766, 0, 0, 0, 0, 926, 0, + 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, + 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, + 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, + 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, + 1025, 1026, 1027, 1028, 1029, 1030, 777, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 925, 0, 0, 636, 0, 0, 923, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 976, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 977, 978, + 259, 659, 822, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 830, 831, 283, + 310, 907, 906, 905, 309, 311, 903, 904, 902, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 913, 935, 924, 788, 789, 914, 915, 939, + 916, 791, 792, 936, 937, 785, 786, 790, 938, 940, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 927, 774, + 773, 0, 780, 781, 0, 810, 811, 813, 819, 820, + 821, 832, 879, 880, 888, 890, 891, 889, 892, 893, + 894, 897, 898, 899, 900, 895, 896, 901, 793, 797, + 794, 795, 796, 808, 798, 799, 800, 801, 802, 803, + 804, 805, 806, 807, 809, 950, 951, 952, 953, 954, + 955, 825, 829, 828, 826, 827, 823, 824, 851, 850, + 852, 853, 854, 855, 856, 857, 859, 858, 860, 861, + 862, 863, 864, 865, 833, 834, 837, 838, 836, 835, + 839, 848, 849, 840, 841, 842, 843, 844, 845, 847, + 846, 866, 867, 868, 869, 870, 872, 871, 875, 876, + 874, 873, 878, 877, 772, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 941, 265, 942, + 0, 0, 946, 0, 0, 0, 948, 947, 0, 949, + 911, 910, 0, 0, 943, 944, 0, 945, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 956, 957, 958, 959, + 960, 961, 962, 963, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 1031, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 784, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 771, 0, 0, 0, + 273, 776, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 783, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 778, 779, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 95, 0, 0, 1032, 513, 966, 755, 932, + 970, 1033, 984, 985, 986, 971, 0, 240, 972, 973, + 247, 974, 0, 931, 814, 816, 815, 881, 882, 883, + 884, 885, 886, 887, 817, 818, 812, 979, 616, 987, + 988, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 751, 768, 0, 782, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 765, 766, + 0, 0, 0, 0, 926, 0, 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, - 1019, 1020, 1021, 1022, 1023, 771, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 919, 0, 0, 630, 0, 0, 917, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 970, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 971, 972, 257, - 653, 816, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 824, 825, 281, 308, - 901, 900, 899, 307, 309, 897, 898, 896, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 907, 929, 918, 782, 783, 908, 909, 933, 910, - 785, 786, 930, 931, 779, 780, 784, 932, 934, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 921, 768, 767, - 0, 774, 775, 0, 804, 805, 807, 813, 814, 815, - 826, 873, 874, 882, 884, 885, 883, 886, 887, 888, - 891, 892, 893, 894, 889, 890, 895, 787, 791, 788, - 789, 790, 802, 792, 793, 794, 795, 796, 797, 798, - 799, 800, 801, 803, 944, 945, 946, 947, 948, 949, - 819, 823, 822, 820, 821, 817, 818, 845, 844, 846, - 847, 848, 849, 850, 851, 853, 852, 854, 855, 856, - 857, 858, 859, 827, 828, 831, 832, 830, 829, 833, - 842, 843, 834, 835, 836, 837, 838, 839, 841, 840, - 860, 861, 862, 863, 864, 866, 865, 869, 870, 868, - 867, 872, 871, 766, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 935, 263, 936, 0, - 0, 940, 0, 0, 0, 942, 941, 0, 943, 905, - 904, 0, 0, 937, 938, 0, 939, 0, 0, 198, - 200, 209, 222, 232, 236, 243, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 950, 951, 952, 953, 954, 955, 956, 957, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 975, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 778, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 765, 0, 0, 0, 271, 770, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 777, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 772, - 773, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 95, 0, 0, - 1024, 508, 960, 749, 926, 964, 1025, 977, 978, 979, - 965, 0, 238, 966, 967, 245, 968, 0, 925, 808, - 810, 809, 875, 876, 877, 878, 879, 880, 881, 811, - 812, 806, 973, 610, 980, 981, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 745, - 762, 0, 776, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 759, 760, 0, 0, 0, 0, 920, - 0, 761, 0, 0, 769, 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, 1012, 1013, 1014, 1015, 1016, - 1017, 1018, 1019, 1020, 1021, 1022, 1023, 3174, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 919, 0, 0, 630, 0, 0, - 917, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 970, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 971, - 972, 257, 653, 816, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 824, 825, - 281, 308, 901, 900, 899, 307, 309, 897, 898, 896, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 907, 929, 918, 782, 783, 908, 909, - 933, 910, 785, 786, 930, 931, 779, 780, 784, 932, - 934, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 921, - 768, 767, 0, 774, 775, 0, 804, 805, 807, 813, - 814, 815, 826, 873, 874, 882, 884, 885, 883, 886, - 887, 888, 891, 892, 893, 894, 889, 890, 895, 787, - 791, 788, 789, 790, 802, 792, 793, 794, 795, 796, - 797, 798, 799, 800, 801, 803, 944, 945, 946, 947, - 948, 949, 819, 823, 822, 820, 821, 817, 818, 845, - 844, 846, 847, 848, 849, 850, 851, 853, 852, 854, - 855, 856, 857, 858, 859, 827, 828, 831, 832, 830, - 829, 833, 842, 843, 834, 835, 836, 837, 838, 839, - 841, 840, 860, 861, 862, 863, 864, 866, 865, 869, - 870, 868, 867, 872, 871, 766, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 935, 263, - 936, 0, 0, 940, 0, 0, 0, 942, 941, 0, - 943, 905, 904, 0, 0, 937, 938, 0, 939, 0, - 0, 198, 200, 209, 222, 232, 236, 243, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 950, 951, 952, 953, 954, 955, 956, - 957, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 975, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 778, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 765, 0, 0, 0, 271, 770, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 777, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 772, 773, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 95, - 0, 0, 1024, 508, 960, 749, 926, 964, 1025, 977, - 978, 979, 965, 0, 238, 966, 967, 245, 968, 0, - 925, 808, 810, 809, 875, 876, 877, 878, 879, 880, - 881, 811, 812, 806, 973, 610, 980, 981, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 745, 762, 0, 776, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 759, 760, 0, 0, 0, - 0, 920, 0, 761, 0, 0, 769, 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, 1012, 1013, 1014, - 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 3170, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 919, 0, 0, 630, - 0, 0, 917, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 970, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 971, 972, 257, 653, 816, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 824, 825, 281, 308, 901, 900, 899, 307, 309, 897, - 898, 896, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 907, 929, 918, 782, 783, - 908, 909, 933, 910, 785, 786, 930, 931, 779, 780, - 784, 932, 934, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 921, 768, 767, 0, 774, 775, 0, 804, 805, - 807, 813, 814, 815, 826, 873, 874, 882, 884, 885, - 883, 886, 887, 888, 891, 892, 893, 894, 889, 890, - 895, 787, 791, 788, 789, 790, 802, 792, 793, 794, - 795, 796, 797, 798, 799, 800, 801, 803, 944, 945, - 946, 947, 948, 949, 819, 823, 822, 820, 821, 817, - 818, 845, 844, 846, 847, 848, 849, 850, 851, 853, - 852, 854, 855, 856, 857, 858, 859, 827, 828, 831, - 832, 830, 829, 833, 842, 843, 834, 835, 836, 837, - 838, 839, 841, 840, 860, 861, 862, 863, 864, 866, - 865, 869, 870, 868, 867, 872, 871, 766, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 935, 263, 936, 0, 0, 940, 0, 0, 0, 942, - 941, 0, 943, 905, 904, 0, 0, 937, 938, 0, - 939, 0, 0, 198, 200, 209, 222, 232, 236, 243, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 950, 951, 952, 953, 954, - 955, 956, 957, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 975, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 778, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 765, 0, 0, 0, 271, - 770, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 777, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 772, 773, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 95, 0, 0, 1024, 508, 960, 1091, 926, 964, - 1025, 977, 978, 979, 965, 0, 238, 966, 967, 245, - 968, 0, 925, 808, 810, 809, 875, 876, 877, 878, - 879, 880, 881, 811, 812, 806, 973, 610, 980, 981, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 762, 0, 776, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 759, 760, 0, - 0, 0, 0, 920, 0, 761, 0, 0, 769, 982, - 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 3193, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 925, + 0, 0, 636, 0, 0, 923, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 976, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 977, 978, 259, 659, 822, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 830, 831, 283, 310, 907, 906, 905, + 309, 311, 903, 904, 902, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 913, 935, + 924, 788, 789, 914, 915, 939, 916, 791, 792, 936, + 937, 785, 786, 790, 938, 940, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 927, 774, 773, 0, 780, 781, + 0, 810, 811, 813, 819, 820, 821, 832, 879, 880, + 888, 890, 891, 889, 892, 893, 894, 897, 898, 899, + 900, 895, 896, 901, 793, 797, 794, 795, 796, 808, + 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, + 809, 950, 951, 952, 953, 954, 955, 825, 829, 828, + 826, 827, 823, 824, 851, 850, 852, 853, 854, 855, + 856, 857, 859, 858, 860, 861, 862, 863, 864, 865, + 833, 834, 837, 838, 836, 835, 839, 848, 849, 840, + 841, 842, 843, 844, 845, 847, 846, 866, 867, 868, + 869, 870, 872, 871, 875, 876, 874, 873, 878, 877, + 772, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 941, 265, 942, 0, 0, 946, 0, + 0, 0, 948, 947, 0, 949, 911, 910, 0, 0, + 943, 944, 0, 945, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 956, 957, 958, 959, 960, 961, 962, 963, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 1031, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 784, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 771, 0, 0, 0, 273, 776, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 783, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 778, 779, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 95, 0, + 0, 1032, 513, 966, 755, 932, 970, 1033, 984, 985, + 986, 971, 0, 240, 972, 973, 247, 974, 0, 931, + 814, 816, 815, 881, 882, 883, 884, 885, 886, 887, + 817, 818, 812, 979, 616, 987, 988, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 751, 768, 0, 782, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 765, 766, 0, 0, 0, 0, + 926, 0, 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 771, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 919, 0, - 0, 630, 0, 0, 917, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 970, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 971, 972, 257, 653, 816, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 824, 825, 281, 308, 901, 900, 899, 307, - 309, 897, 898, 896, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 907, 929, 918, - 782, 783, 908, 909, 933, 910, 785, 786, 930, 931, - 779, 780, 784, 932, 934, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 921, 768, 767, 0, 774, 775, 0, - 804, 805, 807, 813, 814, 815, 826, 873, 874, 882, - 884, 885, 883, 886, 887, 888, 891, 892, 893, 894, - 889, 890, 895, 787, 791, 788, 789, 790, 802, 792, - 793, 794, 795, 796, 797, 798, 799, 800, 801, 803, - 944, 945, 946, 947, 948, 949, 819, 823, 822, 820, - 821, 817, 818, 845, 844, 846, 847, 848, 849, 850, - 851, 853, 852, 854, 855, 856, 857, 858, 859, 827, - 828, 831, 832, 830, 829, 833, 842, 843, 834, 835, - 836, 837, 838, 839, 841, 840, 860, 861, 862, 863, - 864, 866, 865, 869, 870, 868, 867, 872, 871, 766, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 935, 263, 936, 0, 0, 940, 0, 0, - 0, 942, 941, 0, 943, 905, 904, 0, 0, 937, - 938, 0, 939, 0, 0, 198, 200, 209, 222, 232, - 236, 243, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 950, 951, 952, - 953, 954, 955, 956, 957, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 975, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 778, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 765, 0, 0, - 0, 271, 770, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 777, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 772, 773, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 95, 0, 0, 1024, 508, 960, 1091, - 926, 964, 1025, 977, 978, 979, 965, 0, 238, 966, - 967, 245, 968, 0, 925, 808, 810, 809, 875, 876, - 877, 878, 879, 880, 881, 811, 812, 806, 973, 610, - 980, 981, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 762, 0, 776, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 759, - 760, 0, 0, 0, 0, 920, 0, 761, 0, 0, - 769, 982, 983, 984, 985, 986, 987, 988, 989, 990, + 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 3189, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 925, 0, 0, 636, 0, + 0, 923, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 976, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 977, 978, 259, 659, 822, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 830, + 831, 283, 310, 907, 906, 905, 309, 311, 903, 904, + 902, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 913, 935, 924, 788, 789, 914, + 915, 939, 916, 791, 792, 936, 937, 785, 786, 790, + 938, 940, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 927, 774, 773, 0, 780, 781, 0, 810, 811, 813, + 819, 820, 821, 832, 879, 880, 888, 890, 891, 889, + 892, 893, 894, 897, 898, 899, 900, 895, 896, 901, + 793, 797, 794, 795, 796, 808, 798, 799, 800, 801, + 802, 803, 804, 805, 806, 807, 809, 950, 951, 952, + 953, 954, 955, 825, 829, 828, 826, 827, 823, 824, + 851, 850, 852, 853, 854, 855, 856, 857, 859, 858, + 860, 861, 862, 863, 864, 865, 833, 834, 837, 838, + 836, 835, 839, 848, 849, 840, 841, 842, 843, 844, + 845, 847, 846, 866, 867, 868, 869, 870, 872, 871, + 875, 876, 874, 873, 878, 877, 772, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 941, + 265, 942, 0, 0, 946, 0, 0, 0, 948, 947, + 0, 949, 911, 910, 0, 0, 943, 944, 0, 945, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 956, 957, + 958, 959, 960, 961, 962, 963, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 1031, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 784, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 771, 0, + 0, 0, 273, 776, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 783, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 778, 779, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 95, 0, 0, 1032, 513, 966, + 1100, 932, 970, 1033, 984, 985, 986, 971, 0, 240, + 972, 973, 247, 974, 0, 931, 814, 816, 815, 881, + 882, 883, 884, 885, 886, 887, 817, 818, 812, 979, + 616, 987, 988, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 768, 0, 782, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 765, 766, 0, 0, 0, 0, 926, 0, 767, 0, + 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, + 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, + 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, + 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, + 1027, 1028, 1029, 1030, 777, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 925, 0, 0, 636, 0, 0, 923, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 976, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 977, 978, 259, 659, + 822, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 830, 831, 283, 310, 907, + 906, 905, 309, 311, 903, 904, 902, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 913, 935, 924, 788, 789, 914, 915, 939, 916, 791, + 792, 936, 937, 785, 786, 790, 938, 940, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 927, 774, 773, 0, + 780, 781, 0, 810, 811, 813, 819, 820, 821, 832, + 879, 880, 888, 890, 891, 889, 892, 893, 894, 897, + 898, 899, 900, 895, 896, 901, 793, 797, 794, 795, + 796, 808, 798, 799, 800, 801, 802, 803, 804, 805, + 806, 807, 809, 950, 951, 952, 953, 954, 955, 825, + 829, 828, 826, 827, 823, 824, 851, 850, 852, 853, + 854, 855, 856, 857, 859, 858, 860, 861, 862, 863, + 864, 865, 833, 834, 837, 838, 836, 835, 839, 848, + 849, 840, 841, 842, 843, 844, 845, 847, 846, 866, + 867, 868, 869, 870, 872, 871, 875, 876, 874, 873, + 878, 877, 772, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 941, 265, 942, 0, 0, + 946, 0, 0, 0, 948, 947, 0, 949, 911, 910, + 0, 0, 943, 944, 0, 945, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 956, 957, 958, 959, 960, 961, + 962, 963, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 1031, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 784, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 771, 0, 0, 0, 273, 776, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 783, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 778, 779, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 95, 0, 0, 1032, 513, 966, 1100, 932, 970, 1033, + 984, 985, 986, 971, 0, 240, 972, 973, 247, 974, + 0, 931, 814, 816, 815, 881, 882, 883, 884, 885, + 886, 887, 817, 818, 812, 979, 616, 987, 988, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 768, 0, 782, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 765, 766, 0, 0, + 0, 0, 926, 0, 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, - 1021, 1022, 1023, 2124, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 919, 0, 0, 630, 0, 0, 917, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 970, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 971, 972, 257, 653, 816, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 824, 825, 281, 308, 901, 900, - 899, 307, 309, 897, 898, 896, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 907, - 929, 918, 782, 783, 908, 909, 933, 910, 785, 786, - 930, 931, 779, 780, 784, 932, 934, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 921, 768, 767, 0, 774, - 775, 0, 804, 805, 807, 813, 814, 815, 826, 873, - 874, 882, 884, 885, 883, 886, 887, 888, 891, 892, - 893, 894, 889, 890, 895, 787, 791, 788, 789, 790, - 802, 792, 793, 794, 795, 796, 797, 798, 799, 800, - 801, 803, 944, 945, 946, 947, 948, 949, 819, 823, - 822, 820, 821, 817, 818, 845, 844, 846, 847, 848, - 849, 850, 851, 853, 852, 854, 855, 856, 857, 858, - 859, 827, 828, 831, 832, 830, 829, 833, 842, 843, - 834, 835, 836, 837, 838, 839, 841, 840, 860, 861, - 862, 863, 864, 866, 865, 869, 870, 868, 867, 872, - 871, 766, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 935, 263, 936, 0, 0, 940, - 0, 0, 0, 942, 941, 0, 943, 905, 904, 0, - 0, 937, 938, 0, 939, 0, 0, 198, 200, 209, - 222, 232, 236, 243, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 950, - 951, 952, 953, 954, 955, 956, 957, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 975, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 778, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 765, - 0, 0, 0, 271, 770, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 777, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 772, 773, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 95, 0, 0, 1024, 508, - 960, 1091, 926, 964, 1025, 977, 978, 979, 965, 0, - 238, 966, 967, 245, 968, 0, 925, 808, 810, 809, - 875, 876, 877, 878, 879, 880, 881, 811, 812, 806, - 973, 610, 980, 981, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 762, 0, - 776, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 759, 760, 0, 0, 0, 0, 920, 0, 761, - 0, 0, 769, 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, 1012, 1013, 1014, 1015, 1016, 1017, 1018, - 1019, 1020, 1021, 1022, 1023, 2122, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 919, 0, 0, 630, 0, 0, 917, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 970, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 971, 972, 257, - 653, 816, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 824, 825, 281, 308, - 901, 900, 899, 307, 309, 897, 898, 896, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 907, 929, 918, 782, 783, 908, 909, 933, 910, - 785, 786, 930, 931, 779, 780, 784, 932, 934, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 921, 768, 767, - 0, 774, 775, 0, 804, 805, 807, 813, 814, 815, - 826, 873, 874, 882, 884, 885, 883, 886, 887, 888, - 891, 892, 893, 894, 889, 890, 895, 787, 791, 788, - 789, 790, 802, 792, 793, 794, 795, 796, 797, 798, - 799, 800, 801, 803, 944, 945, 946, 947, 948, 949, - 819, 823, 822, 820, 821, 817, 818, 845, 844, 846, - 847, 848, 849, 850, 851, 853, 852, 854, 855, 856, - 857, 858, 859, 827, 828, 831, 832, 830, 829, 833, - 842, 843, 834, 835, 836, 837, 838, 839, 841, 840, - 860, 861, 862, 863, 864, 866, 865, 869, 870, 868, - 867, 872, 871, 766, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 935, 263, 936, 0, - 0, 940, 0, 0, 0, 942, 941, 0, 943, 905, - 904, 0, 0, 937, 938, 0, 939, 0, 0, 198, - 200, 209, 222, 232, 236, 243, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 950, 951, 952, 953, 954, 955, 956, 957, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 975, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 0, 508, 725, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 1142, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 0, 1141, 630, 0, 0, - 0, 0, 0, 1138, 1139, 366, 1099, 331, 197, 225, - 1132, 1136, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 86, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 95, - 0, 0, 0, 508, 194, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 94, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 0, 0, 0, 0, 0, 0, 2427, 0, - 0, 2426, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 209, 222, 232, 236, 243, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 1777, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 1779, 0, 0, 0, 0, 271, - 0, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 0, 0, 0, 1781, 508, 725, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 1480, - 0, 1481, 1482, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 86, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 95, 0, 1754, 0, 508, 725, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 94, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 95, 0, 0, 0, 508, - 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 0, 0, - 0, 0, 0, 0, 2427, 0, 0, 2426, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 209, 222, 232, 236, 243, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 2374, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 1962, 508, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 0, 0, 630, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 2372, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 0, 508, 725, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 1093, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 0, 0, 0, 0, 366, 1099, 331, - 197, 225, 1097, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 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, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 2374, 0, 0, 0, 0, 271, - 0, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 0, 0, 0, 1962, 508, 194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 1754, 0, 508, 725, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 3729, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 2133, 508, - 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2134, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 2881, 508, 725, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 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, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 0, 0, 630, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 0, 508, 725, 0, 0, 0, 0, 2866, - 0, 0, 0, 0, 238, 0, 0, 245, 2867, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 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, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 0, 0, 0, 0, 271, - 1800, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 0, 0, 0, 1799, 508, 725, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 0, 0, 508, 727, 728, - 729, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 0, 508, - 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 4073, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 1962, 508, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 0, 0, 630, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 0, 508, 725, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 3729, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 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, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 0, 0, 0, 0, 271, - 0, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 95, 0, 0, 0, 508, 725, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 0, 0, 0, 2428, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 0, 0, 508, 194, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 1781, 508, - 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 0, 508, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 0, 0, 630, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 2080, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 2071, 508, 725, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 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, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 0, 0, 0, 0, 271, - 0, 0, 0, 0, 367, 268, 0, 1929, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 0, 0, 0, 0, 508, 725, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 1927, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 0, 0, 508, 725, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 1925, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 0, 508, - 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 1923, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 0, 508, 725, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 0, 0, 630, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 0, 0, 367, 268, 0, 1921, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 0, 508, 725, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 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, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 0, 0, 0, 0, 271, - 0, 0, 0, 0, 367, 268, 0, 1917, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 0, 0, 0, 0, 508, 725, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 1915, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 0, 0, 508, 725, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 1913, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 0, 508, - 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 1888, 0, 0, - 0, 508, 725, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 0, 0, 630, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 1785, 271, 0, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 0, 508, 194, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 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, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 410, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 0, 0, 0, 0, 271, - 0, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 95, 0, 0, 0, 508, 960, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 0, 0, 508, 194, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1457, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 1456, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 0, 508, - 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1050, 0, 0, 0, 198, - 200, 209, 222, 232, 236, 243, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 397, 0, 377, 577, - 578, 317, 0, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, - 367, 268, 0, 0, 204, 506, 0, 431, 0, 203, - 0, 488, 253, 378, 375, 584, 283, 274, 270, 250, - 318, 386, 429, 519, 423, 0, 371, 0, 0, 498, - 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, - 248, 326, 202, 414, 499, 287, 0, 0, 0, 0, - 0, 508, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 238, 0, 0, 245, 0, 0, 0, 352, - 361, 360, 340, 341, 343, 345, 351, 358, 364, 337, - 346, 0, 0, 610, 0, 0, 0, 266, 322, 273, - 265, 581, 0, 0, 0, 0, 0, 0, 597, 0, - 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, - 403, 258, 0, 454, 0, 676, 0, 630, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 331, 197, 225, - 0, 0, 413, 462, 474, 0, 0, 0, 254, 0, - 472, 427, 605, 233, 285, 459, 433, 470, 441, 288, - 0, 0, 471, 373, 586, 451, 602, 631, 632, 264, - 407, 616, 523, 624, 649, 226, 261, 421, 507, 608, - 495, 398, 582, 583, 330, 494, 296, 201, 370, 637, - 224, 480, 372, 242, 231, 588, 613, 300, 252, 290, - 457, 644, 213, 518, 599, 239, 484, 0, 0, 652, - 247, 505, 611, 600, 215, 595, 504, 394, 327, 328, - 214, 0, 458, 269, 294, 0, 0, 259, 416, 590, - 591, 257, 653, 228, 623, 220, 0, 622, 409, 585, - 596, 395, 384, 219, 594, 393, 383, 335, 356, 357, - 281, 308, 448, 376, 449, 307, 309, 405, 404, 406, - 207, 609, 627, 0, 208, 0, 500, 612, 654, 453, - 212, 234, 235, 237, 0, 280, 284, 292, 295, 304, - 305, 314, 368, 420, 447, 443, 452, 0, 580, 603, - 617, 629, 635, 636, 638, 639, 640, 641, 642, 645, - 643, 408, 312, 496, 334, 374, 0, 0, 426, 473, - 240, 607, 497, 199, 0, 0, 0, 0, 255, 256, - 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 655, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 666, 667, 668, 669, 670, 671, 672, 650, - 509, 515, 510, 511, 512, 513, 514, 0, 516, 0, - 0, 0, 0, 0, 399, 0, 592, 593, 673, 385, - 487, 604, 336, 350, 353, 342, 362, 0, 363, 338, - 339, 344, 347, 348, 349, 354, 355, 359, 365, 249, - 210, 391, 400, 579, 313, 216, 217, 218, 525, 526, - 527, 528, 620, 621, 625, 205, 463, 464, 465, 466, - 293, 615, 310, 469, 468, 332, 333, 380, 450, 541, - 543, 554, 558, 560, 562, 568, 571, 542, 544, 555, - 559, 561, 563, 569, 572, 531, 533, 535, 537, 550, - 549, 546, 574, 575, 552, 557, 536, 548, 553, 566, - 573, 570, 530, 534, 538, 547, 565, 564, 545, 556, - 567, 551, 539, 532, 540, 0, 196, 221, 369, 0, - 455, 289, 651, 619, 485, 614, 206, 223, 0, 263, - 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, 262, 277, - 279, 286, 299, 311, 319, 320, 323, 329, 381, 387, - 388, 389, 390, 410, 411, 412, 415, 418, 419, 422, - 424, 425, 428, 432, 436, 437, 438, 440, 442, 444, - 456, 461, 475, 476, 477, 478, 479, 482, 483, 489, - 490, 491, 492, 493, 501, 502, 517, 587, 589, 606, - 626, 633, 481, 302, 303, 445, 446, 315, 316, 647, - 648, 301, 601, 634, 598, 646, 628, 439, 379, 0, - 0, 382, 282, 306, 321, 0, 618, 503, 227, 467, - 291, 251, 0, 0, 211, 246, 230, 260, 275, 278, - 325, 392, 401, 430, 435, 297, 272, 244, 460, 241, - 486, 520, 521, 522, 524, 396, 267, 434, 397, 0, - 377, 577, 578, 317, 0, 0, 0, 529, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 0, 0, 367, 268, 0, 0, 204, 506, 0, 431, - 0, 203, 0, 488, 253, 378, 375, 584, 283, 274, - 270, 250, 318, 386, 429, 519, 423, 0, 371, 0, - 0, 498, 402, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 248, 326, 202, 414, 499, 287, 0, 0, - 0, 0, 0, 508, 725, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, - 0, 352, 361, 360, 340, 341, 343, 345, 351, 358, - 364, 337, 346, 0, 0, 610, 0, 0, 0, 266, - 322, 273, 265, 581, 0, 0, 0, 0, 0, 0, - 597, 0, 0, 229, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 298, 0, 403, 258, 0, 454, 0, 0, 0, 630, - 0, 0, 0, 0, 0, 0, 0, 366, 0, 331, - 197, 225, 0, 0, 413, 462, 474, 0, 0, 0, - 254, 0, 472, 427, 605, 233, 285, 459, 433, 470, - 441, 288, 0, 0, 471, 373, 586, 451, 602, 631, - 632, 264, 407, 616, 523, 624, 649, 226, 261, 421, - 507, 608, 495, 398, 582, 583, 330, 494, 296, 201, - 370, 637, 224, 480, 372, 242, 231, 588, 613, 300, - 252, 290, 457, 644, 213, 518, 599, 239, 484, 0, - 0, 652, 247, 505, 611, 600, 215, 595, 504, 394, - 327, 328, 214, 0, 458, 269, 294, 0, 0, 259, - 416, 590, 591, 257, 653, 228, 623, 220, 0, 622, - 409, 585, 596, 395, 384, 219, 594, 393, 383, 335, - 356, 357, 281, 308, 448, 376, 449, 307, 309, 405, - 404, 406, 207, 609, 627, 0, 208, 0, 500, 612, - 654, 453, 212, 234, 235, 237, 0, 280, 284, 292, - 295, 304, 305, 314, 368, 420, 447, 443, 452, 0, - 580, 603, 617, 629, 635, 636, 638, 639, 640, 641, - 642, 645, 643, 408, 312, 496, 334, 374, 0, 0, - 426, 473, 240, 607, 497, 199, 0, 0, 0, 0, - 255, 256, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 650, 509, 515, 510, 511, 512, 513, 514, 0, - 516, 0, 0, 0, 0, 0, 399, 0, 592, 593, - 673, 385, 487, 604, 336, 350, 353, 342, 362, 0, - 363, 338, 339, 344, 347, 348, 349, 354, 355, 359, - 365, 249, 210, 391, 400, 579, 313, 216, 217, 218, - 525, 526, 527, 528, 620, 621, 625, 205, 463, 464, - 465, 466, 293, 615, 310, 469, 468, 332, 333, 380, - 450, 541, 543, 554, 558, 560, 562, 568, 571, 542, - 544, 555, 559, 561, 563, 569, 572, 531, 533, 535, - 537, 550, 549, 546, 574, 575, 552, 557, 536, 548, - 553, 566, 573, 570, 530, 534, 538, 547, 565, 564, - 545, 556, 567, 551, 539, 532, 540, 0, 196, 221, - 369, 0, 455, 289, 651, 619, 485, 614, 206, 223, - 0, 263, 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, - 262, 277, 279, 286, 299, 311, 319, 320, 323, 329, - 381, 387, 388, 389, 390, 4139, 411, 412, 415, 418, - 419, 422, 424, 425, 428, 432, 436, 437, 438, 440, - 442, 444, 456, 461, 475, 476, 477, 478, 479, 482, - 483, 489, 490, 491, 492, 493, 501, 502, 517, 587, - 589, 606, 626, 633, 481, 302, 303, 445, 446, 315, - 316, 647, 648, 301, 601, 634, 598, 646, 628, 439, - 379, 0, 0, 382, 282, 306, 321, 0, 618, 503, - 227, 467, 291, 251, 0, 0, 211, 246, 230, 260, - 275, 278, 325, 392, 401, 430, 435, 297, 272, 244, - 460, 241, 486, 520, 521, 522, 524, 396, 267, 434, - 397, 0, 377, 577, 578, 317, 0, 0, 0, 529, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 0, 0, 0, 0, 271, - 0, 0, 0, 0, 367, 268, 0, 0, 204, 506, - 0, 431, 0, 203, 0, 488, 253, 378, 375, 584, - 283, 274, 270, 250, 318, 386, 429, 519, 423, 0, - 371, 0, 0, 498, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 324, 248, 326, 202, 414, 499, 287, - 0, 0, 0, 0, 0, 508, 725, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, - 0, 0, 0, 352, 361, 360, 340, 341, 343, 345, - 351, 358, 364, 337, 346, 0, 0, 610, 0, 0, - 0, 266, 322, 273, 265, 581, 0, 0, 0, 0, - 0, 0, 597, 0, 0, 229, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 298, 0, 403, 258, 0, 454, 0, 0, - 0, 630, 0, 0, 0, 0, 0, 0, 0, 366, - 0, 331, 197, 225, 0, 0, 413, 462, 474, 0, - 0, 0, 254, 0, 472, 427, 605, 233, 285, 459, - 433, 470, 441, 288, 0, 0, 471, 373, 586, 451, - 602, 631, 632, 264, 407, 616, 523, 624, 649, 226, - 261, 421, 507, 608, 495, 398, 582, 583, 330, 494, - 296, 201, 370, 637, 224, 480, 372, 242, 231, 588, - 613, 300, 252, 290, 457, 644, 213, 518, 599, 239, - 484, 0, 0, 652, 247, 505, 611, 600, 215, 595, - 504, 394, 327, 328, 214, 0, 458, 269, 294, 0, - 0, 259, 416, 590, 591, 257, 653, 228, 623, 220, - 0, 622, 409, 585, 596, 395, 384, 219, 594, 393, - 383, 335, 356, 357, 281, 308, 448, 376, 449, 307, - 309, 405, 404, 406, 207, 609, 627, 0, 208, 0, - 500, 612, 654, 453, 212, 234, 235, 237, 0, 280, - 284, 292, 295, 304, 305, 314, 368, 420, 447, 443, - 452, 0, 580, 603, 617, 629, 635, 636, 638, 639, - 640, 641, 642, 645, 643, 408, 312, 496, 334, 374, - 0, 0, 426, 473, 240, 607, 497, 199, 0, 0, - 0, 0, 255, 256, 0, 576, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 655, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 670, 671, 672, 650, 509, 515, 510, 511, 512, 513, - 514, 0, 516, 0, 0, 0, 0, 0, 399, 0, - 592, 593, 673, 385, 487, 604, 336, 350, 353, 342, - 362, 0, 363, 338, 339, 344, 347, 348, 349, 354, - 355, 359, 365, 249, 210, 391, 400, 579, 313, 216, - 217, 218, 525, 526, 527, 528, 620, 621, 625, 205, - 463, 464, 465, 466, 293, 615, 310, 469, 468, 332, - 333, 380, 450, 541, 543, 554, 558, 560, 562, 568, - 571, 542, 544, 555, 559, 561, 563, 569, 572, 531, - 533, 535, 537, 550, 549, 546, 574, 575, 552, 557, - 536, 548, 553, 566, 573, 570, 530, 534, 538, 547, - 565, 564, 545, 556, 567, 551, 539, 532, 540, 0, - 196, 221, 369, 0, 455, 289, 651, 619, 485, 614, - 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, 319, 320, - 323, 329, 381, 387, 388, 389, 390, 410, 411, 412, - 415, 418, 419, 422, 424, 425, 428, 432, 436, 437, - 438, 440, 442, 444, 456, 461, 475, 476, 477, 478, - 479, 482, 483, 489, 490, 491, 492, 493, 501, 502, - 517, 587, 589, 606, 626, 633, 481, 302, 303, 445, - 446, 315, 316, 647, 648, 301, 601, 634, 598, 646, - 628, 439, 379, 0, 0, 382, 282, 306, 321, 0, - 618, 503, 227, 467, 291, 251, 0, 0, 211, 246, - 230, 260, 275, 278, 325, 392, 401, 430, 435, 297, - 272, 244, 460, 241, 486, 520, 521, 522, 524, 396, - 267, 434, 397, 0, 377, 577, 578, 317, 0, 0, - 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 0, 0, 0, 367, 268, 0, 0, - 204, 506, 0, 431, 0, 203, 0, 488, 253, 378, - 375, 584, 283, 274, 270, 250, 318, 386, 429, 519, - 423, 0, 371, 0, 0, 498, 402, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 324, 248, 326, 202, 414, - 499, 287, 0, 0, 0, 0, 0, 508, 960, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 245, 0, 0, 0, 352, 361, 360, 340, 341, - 343, 345, 351, 358, 364, 337, 346, 0, 0, 610, - 0, 0, 0, 266, 322, 273, 265, 581, 0, 0, - 0, 0, 0, 0, 597, 0, 0, 229, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 403, 258, 0, 454, - 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 331, 197, 225, 0, 0, 413, 462, - 474, 0, 0, 0, 254, 0, 472, 427, 605, 233, - 285, 459, 433, 470, 441, 288, 0, 0, 471, 373, - 586, 451, 602, 631, 632, 264, 407, 616, 523, 624, - 649, 226, 261, 421, 507, 608, 495, 398, 582, 583, - 330, 494, 296, 201, 370, 637, 224, 480, 372, 242, - 231, 588, 613, 300, 252, 290, 457, 644, 213, 518, - 599, 239, 484, 0, 0, 652, 247, 505, 611, 600, - 215, 595, 504, 394, 327, 328, 214, 0, 458, 269, - 294, 0, 0, 259, 416, 590, 591, 257, 653, 228, - 623, 220, 0, 622, 409, 585, 596, 395, 384, 219, - 594, 393, 383, 335, 356, 357, 281, 308, 448, 376, - 449, 307, 309, 405, 404, 406, 207, 609, 627, 0, - 208, 0, 500, 612, 654, 453, 212, 234, 235, 237, - 0, 280, 284, 292, 295, 304, 305, 314, 368, 420, - 447, 443, 452, 0, 580, 603, 617, 629, 635, 636, - 638, 639, 640, 641, 642, 645, 643, 408, 312, 496, - 334, 374, 0, 0, 426, 473, 240, 607, 497, 199, - 0, 0, 0, 0, 255, 256, 0, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, - 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, - 668, 669, 670, 671, 672, 650, 509, 515, 510, 511, - 512, 513, 514, 0, 516, 0, 0, 0, 0, 0, - 399, 0, 592, 593, 673, 385, 487, 604, 336, 350, - 353, 342, 362, 0, 363, 338, 339, 344, 347, 348, - 349, 354, 355, 359, 365, 249, 210, 391, 400, 579, - 313, 216, 217, 218, 525, 526, 527, 528, 620, 621, - 625, 205, 463, 464, 465, 466, 293, 615, 310, 469, - 468, 332, 333, 380, 450, 541, 543, 554, 558, 560, - 562, 568, 571, 542, 544, 555, 559, 561, 563, 569, - 572, 531, 533, 535, 537, 550, 549, 546, 574, 575, - 552, 557, 536, 548, 553, 566, 573, 570, 530, 534, - 538, 547, 565, 564, 545, 556, 567, 551, 539, 532, - 540, 0, 196, 221, 369, 0, 455, 289, 651, 619, - 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, 299, 311, - 319, 320, 323, 329, 381, 387, 388, 389, 390, 410, - 411, 412, 415, 418, 419, 422, 424, 425, 428, 432, - 436, 437, 438, 440, 442, 444, 456, 461, 475, 476, - 477, 478, 479, 482, 483, 489, 490, 491, 492, 493, - 501, 502, 517, 587, 589, 606, 626, 633, 481, 302, - 303, 445, 446, 315, 316, 647, 648, 301, 601, 634, - 598, 646, 628, 439, 379, 0, 0, 382, 282, 306, - 321, 0, 618, 503, 227, 467, 291, 251, 0, 0, - 211, 246, 230, 260, 275, 278, 325, 392, 401, 430, - 435, 297, 272, 244, 460, 241, 486, 520, 521, 522, - 524, 396, 267, 434, 397, 0, 377, 577, 578, 317, - 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 367, 268, - 0, 0, 204, 506, 0, 431, 0, 203, 0, 488, - 253, 378, 375, 584, 283, 274, 270, 250, 318, 386, - 429, 519, 423, 0, 371, 0, 0, 498, 402, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 248, 326, - 202, 414, 499, 287, 0, 0, 0, 0, 0, 508, - 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 238, 0, 0, 245, 0, 0, 0, 352, 361, 360, - 340, 341, 343, 345, 351, 358, 364, 337, 346, 0, - 0, 610, 0, 0, 0, 266, 322, 273, 265, 581, - 0, 0, 0, 0, 0, 0, 597, 0, 0, 229, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 298, 0, 403, 258, - 0, 454, 0, 0, 0, 630, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 331, 197, 225, 0, 0, - 413, 462, 474, 0, 0, 0, 254, 0, 472, 427, - 605, 233, 285, 459, 433, 470, 441, 288, 0, 0, - 471, 373, 586, 451, 602, 631, 632, 264, 407, 616, - 523, 624, 649, 226, 261, 421, 507, 608, 495, 398, - 582, 583, 330, 494, 296, 201, 370, 637, 224, 480, - 372, 242, 231, 588, 613, 300, 252, 290, 457, 644, - 213, 518, 599, 239, 484, 0, 0, 652, 247, 505, - 611, 600, 215, 595, 504, 394, 327, 328, 214, 0, - 458, 269, 294, 0, 0, 259, 416, 590, 591, 257, - 653, 228, 623, 220, 0, 622, 409, 585, 596, 395, - 384, 219, 594, 393, 383, 335, 356, 357, 281, 308, - 448, 376, 449, 307, 309, 405, 404, 406, 207, 609, - 627, 0, 208, 0, 500, 612, 654, 453, 212, 234, - 235, 237, 0, 280, 284, 292, 295, 304, 305, 314, - 368, 420, 447, 443, 452, 0, 580, 603, 617, 629, - 635, 636, 638, 639, 640, 641, 642, 645, 643, 408, - 312, 496, 334, 374, 0, 0, 426, 473, 240, 607, - 497, 199, 0, 0, 0, 0, 255, 256, 0, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 650, 509, 515, - 510, 511, 512, 513, 514, 0, 516, 0, 0, 0, - 0, 0, 399, 0, 592, 593, 673, 385, 487, 604, - 336, 350, 353, 342, 362, 0, 363, 338, 339, 344, - 347, 348, 349, 354, 355, 359, 365, 249, 210, 391, - 400, 579, 313, 216, 217, 218, 525, 526, 527, 528, - 620, 621, 625, 205, 463, 464, 465, 466, 293, 615, - 310, 469, 468, 332, 333, 380, 450, 541, 543, 554, - 558, 560, 562, 568, 571, 542, 544, 555, 559, 561, - 563, 569, 572, 531, 533, 535, 537, 550, 549, 546, - 574, 575, 552, 557, 536, 548, 553, 566, 573, 570, - 530, 534, 538, 547, 565, 564, 545, 556, 567, 551, - 539, 532, 540, 0, 196, 221, 369, 0, 455, 289, - 651, 619, 485, 614, 206, 223, 0, 263, 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, 262, 277, 279, 286, - 299, 311, 319, 320, 323, 329, 381, 387, 388, 389, - 390, 410, 411, 412, 415, 418, 419, 422, 424, 425, - 428, 432, 436, 437, 438, 440, 442, 444, 456, 461, - 475, 476, 477, 478, 479, 482, 483, 489, 490, 491, - 492, 493, 501, 502, 517, 587, 589, 606, 626, 633, - 481, 302, 303, 445, 446, 315, 316, 647, 648, 301, - 601, 634, 598, 646, 628, 439, 379, 0, 0, 382, - 282, 306, 321, 0, 618, 503, 227, 467, 291, 251, - 0, 0, 211, 246, 230, 260, 275, 278, 325, 392, - 401, 430, 435, 297, 272, 244, 460, 241, 486, 520, - 521, 522, 524, 396, 267, 434, 0, 0, 377, 577, - 578, 317, + 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, + 2139, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 925, 0, 0, + 636, 0, 0, 923, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 976, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 977, 978, 259, 659, 822, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 830, 831, 283, 310, 907, 906, 905, 309, 311, + 903, 904, 902, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 913, 935, 924, 788, + 789, 914, 915, 939, 916, 791, 792, 936, 937, 785, + 786, 790, 938, 940, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 927, 774, 773, 0, 780, 781, 0, 810, + 811, 813, 819, 820, 821, 832, 879, 880, 888, 890, + 891, 889, 892, 893, 894, 897, 898, 899, 900, 895, + 896, 901, 793, 797, 794, 795, 796, 808, 798, 799, + 800, 801, 802, 803, 804, 805, 806, 807, 809, 950, + 951, 952, 953, 954, 955, 825, 829, 828, 826, 827, + 823, 824, 851, 850, 852, 853, 854, 855, 856, 857, + 859, 858, 860, 861, 862, 863, 864, 865, 833, 834, + 837, 838, 836, 835, 839, 848, 849, 840, 841, 842, + 843, 844, 845, 847, 846, 866, 867, 868, 869, 870, + 872, 871, 875, 876, 874, 873, 878, 877, 772, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 941, 265, 942, 0, 0, 946, 0, 0, 0, + 948, 947, 0, 949, 911, 910, 0, 0, 943, 944, + 0, 945, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 956, 957, 958, 959, 960, 961, 962, 963, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 1031, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 784, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 771, 0, 0, 0, 273, 776, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 783, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 778, 779, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 95, 0, 0, 1032, + 513, 966, 1100, 932, 970, 1033, 984, 985, 986, 971, + 0, 240, 972, 973, 247, 974, 0, 931, 814, 816, + 815, 881, 882, 883, 884, 885, 886, 887, 817, 818, + 812, 979, 616, 987, 988, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 768, + 0, 782, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 765, 766, 0, 0, 0, 0, 926, 0, + 767, 0, 0, 775, 989, 990, 991, 992, 993, 994, + 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, + 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, + 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, + 1025, 1026, 1027, 1028, 1029, 1030, 2137, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 925, 0, 0, 636, 0, 0, 923, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 976, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 977, 978, + 259, 659, 822, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 830, 831, 283, + 310, 907, 906, 905, 309, 311, 903, 904, 902, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 913, 935, 924, 788, 789, 914, 915, 939, + 916, 791, 792, 936, 937, 785, 786, 790, 938, 940, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 927, 774, + 773, 0, 780, 781, 0, 810, 811, 813, 819, 820, + 821, 832, 879, 880, 888, 890, 891, 889, 892, 893, + 894, 897, 898, 899, 900, 895, 896, 901, 793, 797, + 794, 795, 796, 808, 798, 799, 800, 801, 802, 803, + 804, 805, 806, 807, 809, 950, 951, 952, 953, 954, + 955, 825, 829, 828, 826, 827, 823, 824, 851, 850, + 852, 853, 854, 855, 856, 857, 859, 858, 860, 861, + 862, 863, 864, 865, 833, 834, 837, 838, 836, 835, + 839, 848, 849, 840, 841, 842, 843, 844, 845, 847, + 846, 866, 867, 868, 869, 870, 872, 871, 875, 876, + 874, 873, 878, 877, 772, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 941, 265, 942, + 0, 0, 946, 0, 0, 0, 948, 947, 0, 949, + 911, 910, 0, 0, 943, 944, 0, 945, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 956, 957, 958, 959, + 960, 961, 962, 963, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 1031, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 0, 0, 0, 0, 513, 731, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 1151, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 0, 1150, 636, 0, 0, 0, 0, 0, 1147, 1148, + 368, 1108, 333, 199, 227, 1141, 1145, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 86, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 97, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 95, 0, + 0, 0, 513, 196, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 94, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 2444, 0, 0, + 2443, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 86, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, + 0, 0, 273, 0, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 97, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 95, 0, 1764, 0, 513, 731, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 94, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 1792, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 1794, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 1796, 513, 731, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 1489, 0, + 1490, 1491, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 95, 0, 0, 0, + 513, 196, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 2444, 0, 0, 2443, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 2389, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 0, 0, 0, 1977, 513, 196, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 2387, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 0, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 731, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 1102, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 0, 368, 1108, 333, 199, + 227, 1106, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 2389, 0, 0, + 0, 0, 273, 0, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 0, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 0, 0, 0, 1977, 513, 196, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 1764, 0, 513, 731, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 3748, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 2148, + 513, 731, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2149, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 0, 0, 0, 2900, 513, 731, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2901, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 0, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 731, 0, 0, 0, 0, 2883, 0, + 0, 0, 0, 240, 0, 0, 247, 2884, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, + 0, 0, 273, 1815, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 0, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 0, 0, 0, 1814, 513, 731, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 0, 513, 733, 734, 735, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 0, + 513, 731, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 4092, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 0, 0, 0, 1977, 513, 196, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 0, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 731, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 3748, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, + 0, 0, 273, 0, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 0, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 95, 0, 0, 0, 513, 731, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 2445, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 0, 513, 196, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 1796, + 513, 731, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 0, 0, 0, 0, 513, 196, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 2095, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 0, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 2086, 513, 731, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, + 0, 0, 273, 0, 0, 0, 0, 369, 270, 0, + 1944, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 0, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 0, 0, 0, 0, 513, 731, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 1942, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 0, 513, 731, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 1940, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 0, + 513, 731, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 1938, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 0, 0, 0, 0, 513, 731, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, + 0, 369, 270, 0, 1936, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 0, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 731, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, + 0, 0, 273, 0, 0, 0, 0, 369, 270, 0, + 1932, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 0, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 0, 0, 0, 0, 513, 731, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 1930, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 0, 513, 731, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 1928, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 0, + 513, 731, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 1903, 0, 0, 0, 513, 731, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 1800, 273, 0, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 0, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 196, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 413, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, + 0, 0, 273, 0, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 0, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 95, 0, 0, 0, 513, 966, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 0, 513, 196, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1466, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 1465, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 0, + 513, 196, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1058, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 400, 0, 379, 582, 583, 319, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, + 273, 0, 0, 0, 0, 369, 270, 0, 0, 206, + 511, 0, 435, 0, 205, 0, 493, 255, 380, 377, + 590, 285, 276, 272, 252, 320, 389, 432, 524, 426, + 0, 373, 0, 0, 503, 405, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 326, 250, 328, 204, 417, 504, + 289, 0, 0, 0, 0, 0, 513, 196, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, + 247, 0, 0, 0, 354, 363, 362, 342, 343, 345, + 347, 353, 360, 366, 339, 348, 0, 0, 616, 0, + 0, 0, 268, 324, 275, 267, 587, 0, 0, 0, + 0, 0, 0, 603, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 300, 0, 406, 260, 0, 459, 0, + 682, 0, 636, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 333, 199, 227, 0, 0, 416, 467, 479, + 0, 0, 0, 256, 0, 477, 430, 611, 235, 287, + 464, 437, 475, 445, 290, 0, 0, 476, 375, 592, + 455, 608, 637, 638, 266, 410, 622, 528, 630, 655, + 228, 263, 424, 512, 614, 500, 401, 588, 589, 332, + 499, 298, 203, 372, 643, 226, 485, 374, 244, 233, + 594, 619, 302, 254, 292, 462, 650, 215, 523, 605, + 241, 489, 0, 0, 658, 249, 510, 617, 606, 217, + 601, 509, 397, 329, 330, 216, 0, 463, 271, 296, + 0, 0, 261, 419, 596, 597, 259, 659, 230, 629, + 222, 0, 628, 412, 591, 602, 398, 386, 221, 600, + 396, 385, 337, 358, 359, 283, 310, 452, 378, 453, + 309, 311, 408, 407, 409, 209, 615, 633, 0, 210, + 0, 505, 618, 660, 457, 214, 236, 237, 239, 0, + 282, 286, 294, 297, 306, 307, 316, 370, 423, 451, + 447, 456, 0, 585, 609, 623, 635, 641, 642, 644, + 645, 646, 647, 648, 651, 649, 411, 314, 501, 336, + 376, 0, 0, 429, 478, 242, 613, 502, 201, 0, + 0, 0, 0, 257, 258, 0, 581, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 661, 662, 663, 664, + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, + 675, 676, 677, 678, 656, 514, 520, 515, 516, 517, + 518, 519, 0, 521, 0, 0, 0, 0, 0, 402, + 0, 598, 599, 679, 387, 492, 610, 338, 352, 355, + 344, 364, 0, 365, 340, 341, 346, 349, 350, 351, + 356, 357, 361, 367, 251, 212, 394, 403, 584, 315, + 218, 219, 220, 530, 531, 532, 533, 626, 627, 631, + 207, 468, 469, 470, 471, 295, 621, 312, 474, 473, + 334, 335, 382, 454, 546, 548, 559, 563, 565, 567, + 573, 576, 547, 549, 560, 564, 566, 568, 574, 577, + 536, 538, 540, 542, 555, 554, 551, 579, 580, 557, + 562, 541, 553, 558, 571, 578, 575, 535, 539, 543, + 552, 570, 569, 550, 561, 572, 556, 544, 537, 545, + 0, 198, 223, 371, 0, 460, 291, 657, 625, 490, + 620, 208, 225, 0, 265, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 200, 202, 211, 224, + 234, 238, 245, 264, 279, 281, 288, 301, 313, 321, + 322, 325, 331, 383, 390, 391, 392, 393, 413, 414, + 415, 418, 421, 422, 425, 427, 428, 431, 436, 440, + 441, 442, 444, 446, 448, 461, 466, 480, 481, 482, + 483, 484, 487, 488, 494, 495, 496, 497, 498, 506, + 507, 522, 593, 595, 612, 632, 639, 486, 388, 434, + 458, 586, 304, 305, 449, 450, 317, 318, 653, 654, + 303, 607, 640, 604, 652, 634, 443, 381, 0, 0, + 384, 284, 308, 323, 0, 624, 508, 229, 472, 293, + 253, 0, 0, 213, 248, 232, 262, 277, 280, 327, + 395, 404, 433, 439, 299, 274, 246, 465, 243, 491, + 525, 526, 527, 529, 399, 269, 438, 400, 0, 379, + 582, 583, 319, 0, 0, 0, 534, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, + 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, + 0, 369, 270, 0, 0, 206, 511, 0, 435, 0, + 205, 0, 493, 255, 380, 377, 590, 285, 276, 272, + 252, 320, 389, 432, 524, 426, 0, 373, 0, 0, + 503, 405, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 326, 250, 328, 204, 417, 504, 289, 0, 0, 0, + 0, 0, 513, 731, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 240, 0, 0, 247, 0, 0, 0, + 354, 363, 362, 342, 343, 345, 347, 353, 360, 366, + 339, 348, 0, 0, 616, 0, 0, 0, 268, 324, + 275, 267, 587, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, + 0, 406, 260, 0, 459, 0, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 0, 368, 0, 333, 199, + 227, 0, 0, 416, 467, 479, 0, 0, 0, 256, + 0, 477, 430, 611, 235, 287, 464, 437, 475, 445, + 290, 0, 0, 476, 375, 592, 455, 608, 637, 638, + 266, 410, 622, 528, 630, 655, 228, 263, 424, 512, + 614, 500, 401, 588, 589, 332, 499, 298, 203, 372, + 643, 226, 485, 374, 244, 233, 594, 619, 302, 254, + 292, 462, 650, 215, 523, 605, 241, 489, 0, 0, + 658, 249, 510, 617, 606, 217, 601, 509, 397, 329, + 330, 216, 0, 463, 271, 296, 0, 0, 261, 419, + 596, 597, 259, 659, 230, 629, 222, 0, 628, 412, + 591, 602, 398, 386, 221, 600, 396, 385, 337, 358, + 359, 283, 310, 452, 378, 453, 309, 311, 408, 407, + 409, 209, 615, 633, 0, 210, 0, 505, 618, 660, + 457, 214, 236, 237, 239, 0, 282, 286, 294, 297, + 306, 307, 316, 370, 423, 451, 447, 456, 0, 585, + 609, 623, 635, 641, 642, 644, 645, 646, 647, 648, + 651, 649, 411, 314, 501, 336, 376, 0, 0, 429, + 478, 242, 613, 502, 201, 0, 0, 0, 0, 257, + 258, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 662, 663, 664, 665, 666, 667, 668, + 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, + 656, 514, 520, 515, 516, 517, 518, 519, 0, 521, + 0, 0, 0, 0, 0, 402, 0, 598, 599, 679, + 387, 492, 610, 338, 352, 355, 344, 364, 0, 365, + 340, 341, 346, 349, 350, 351, 356, 357, 361, 367, + 251, 212, 394, 403, 584, 315, 218, 219, 220, 530, + 531, 532, 533, 626, 627, 631, 207, 468, 469, 470, + 471, 295, 621, 312, 474, 473, 334, 335, 382, 454, + 546, 548, 559, 563, 565, 567, 573, 576, 547, 549, + 560, 564, 566, 568, 574, 577, 536, 538, 540, 542, + 555, 554, 551, 579, 580, 557, 562, 541, 553, 558, + 571, 578, 575, 535, 539, 543, 552, 570, 569, 550, + 561, 572, 556, 544, 537, 545, 0, 198, 223, 371, + 0, 460, 291, 657, 625, 490, 620, 208, 225, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 202, 211, 224, 234, 238, 245, 264, + 279, 281, 288, 301, 313, 321, 322, 325, 331, 383, + 390, 391, 392, 393, 4158, 414, 415, 418, 421, 422, + 425, 427, 428, 431, 436, 440, 441, 442, 444, 446, + 448, 461, 466, 480, 481, 482, 483, 484, 487, 488, + 494, 495, 496, 497, 498, 506, 507, 522, 593, 595, + 612, 632, 639, 486, 388, 434, 458, 586, 304, 305, + 449, 450, 317, 318, 653, 654, 303, 607, 640, 604, + 652, 634, 443, 381, 0, 0, 384, 284, 308, 323, + 0, 624, 508, 229, 472, 293, 253, 0, 0, 213, + 248, 232, 262, 277, 280, 327, 395, 404, 433, 439, + 299, 274, 246, 465, 243, 491, 525, 526, 527, 529, + 399, 269, 438, 400, 0, 379, 582, 583, 319, 0, + 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, + 0, 0, 273, 0, 0, 0, 0, 369, 270, 0, + 0, 206, 511, 0, 435, 0, 205, 0, 493, 255, + 380, 377, 590, 285, 276, 272, 252, 320, 389, 432, + 524, 426, 0, 373, 0, 0, 503, 405, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 326, 250, 328, 204, + 417, 504, 289, 0, 0, 0, 0, 0, 513, 731, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, + 0, 0, 247, 0, 0, 0, 354, 363, 362, 342, + 343, 345, 347, 353, 360, 366, 339, 348, 0, 0, + 616, 0, 0, 0, 268, 324, 275, 267, 587, 0, + 0, 0, 0, 0, 0, 603, 0, 0, 231, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 0, 406, 260, 0, + 459, 0, 0, 0, 636, 0, 0, 0, 0, 0, + 0, 0, 368, 0, 333, 199, 227, 0, 0, 416, + 467, 479, 0, 0, 0, 256, 0, 477, 430, 611, + 235, 287, 464, 437, 475, 445, 290, 0, 0, 476, + 375, 592, 455, 608, 637, 638, 266, 410, 622, 528, + 630, 655, 228, 263, 424, 512, 614, 500, 401, 588, + 589, 332, 499, 298, 203, 372, 643, 226, 485, 374, + 244, 233, 594, 619, 302, 254, 292, 462, 650, 215, + 523, 605, 241, 489, 0, 0, 658, 249, 510, 617, + 606, 217, 601, 509, 397, 329, 330, 216, 0, 463, + 271, 296, 0, 0, 261, 419, 596, 597, 259, 659, + 230, 629, 222, 0, 628, 412, 591, 602, 398, 386, + 221, 600, 396, 385, 337, 358, 359, 283, 310, 452, + 378, 453, 309, 311, 408, 407, 409, 209, 615, 633, + 0, 210, 0, 505, 618, 660, 457, 214, 236, 237, + 239, 0, 282, 286, 294, 297, 306, 307, 316, 370, + 423, 451, 447, 456, 0, 585, 609, 623, 635, 641, + 642, 644, 645, 646, 647, 648, 651, 649, 411, 314, + 501, 336, 376, 0, 0, 429, 478, 242, 613, 502, + 201, 0, 0, 0, 0, 257, 258, 0, 581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 656, 514, 520, 515, + 516, 517, 518, 519, 0, 521, 0, 0, 0, 0, + 0, 402, 0, 598, 599, 679, 387, 492, 610, 338, + 352, 355, 344, 364, 0, 365, 340, 341, 346, 349, + 350, 351, 356, 357, 361, 367, 251, 212, 394, 403, + 584, 315, 218, 219, 220, 530, 531, 532, 533, 626, + 627, 631, 207, 468, 469, 470, 471, 295, 621, 312, + 474, 473, 334, 335, 382, 454, 546, 548, 559, 563, + 565, 567, 573, 576, 547, 549, 560, 564, 566, 568, + 574, 577, 536, 538, 540, 542, 555, 554, 551, 579, + 580, 557, 562, 541, 553, 558, 571, 578, 575, 535, + 539, 543, 552, 570, 569, 550, 561, 572, 556, 544, + 537, 545, 0, 198, 223, 371, 0, 460, 291, 657, + 625, 490, 620, 208, 225, 0, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 200, 202, + 211, 224, 234, 238, 245, 264, 279, 281, 288, 301, + 313, 321, 322, 325, 331, 383, 390, 391, 392, 393, + 413, 414, 415, 418, 421, 422, 425, 427, 428, 431, + 436, 440, 441, 442, 444, 446, 448, 461, 466, 480, + 481, 482, 483, 484, 487, 488, 494, 495, 496, 497, + 498, 506, 507, 522, 593, 595, 612, 632, 639, 486, + 388, 434, 458, 586, 304, 305, 449, 450, 317, 318, + 653, 654, 303, 607, 640, 604, 652, 634, 443, 381, + 0, 0, 384, 284, 308, 323, 0, 624, 508, 229, + 472, 293, 253, 0, 0, 213, 248, 232, 262, 277, + 280, 327, 395, 404, 433, 439, 299, 274, 246, 465, + 243, 491, 525, 526, 527, 529, 399, 269, 438, 400, + 0, 379, 582, 583, 319, 0, 0, 0, 534, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 369, 270, 0, 0, 206, 511, 0, + 435, 0, 205, 0, 493, 255, 380, 377, 590, 285, + 276, 272, 252, 320, 389, 432, 524, 426, 0, 373, + 0, 0, 503, 405, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 326, 250, 328, 204, 417, 504, 289, 0, + 0, 0, 0, 0, 513, 966, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 240, 0, 0, 247, 0, + 0, 0, 354, 363, 362, 342, 343, 345, 347, 353, + 360, 366, 339, 348, 0, 0, 616, 0, 0, 0, + 268, 324, 275, 267, 587, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 231, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 300, 0, 406, 260, 0, 459, 0, 0, 0, + 636, 0, 0, 0, 0, 0, 0, 0, 368, 0, + 333, 199, 227, 0, 0, 416, 467, 479, 0, 0, + 0, 256, 0, 477, 430, 611, 235, 287, 464, 437, + 475, 445, 290, 0, 0, 476, 375, 592, 455, 608, + 637, 638, 266, 410, 622, 528, 630, 655, 228, 263, + 424, 512, 614, 500, 401, 588, 589, 332, 499, 298, + 203, 372, 643, 226, 485, 374, 244, 233, 594, 619, + 302, 254, 292, 462, 650, 215, 523, 605, 241, 489, + 0, 0, 658, 249, 510, 617, 606, 217, 601, 509, + 397, 329, 330, 216, 0, 463, 271, 296, 0, 0, + 261, 419, 596, 597, 259, 659, 230, 629, 222, 0, + 628, 412, 591, 602, 398, 386, 221, 600, 396, 385, + 337, 358, 359, 283, 310, 452, 378, 453, 309, 311, + 408, 407, 409, 209, 615, 633, 0, 210, 0, 505, + 618, 660, 457, 214, 236, 237, 239, 0, 282, 286, + 294, 297, 306, 307, 316, 370, 423, 451, 447, 456, + 0, 585, 609, 623, 635, 641, 642, 644, 645, 646, + 647, 648, 651, 649, 411, 314, 501, 336, 376, 0, + 0, 429, 478, 242, 613, 502, 201, 0, 0, 0, + 0, 257, 258, 0, 581, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 662, 663, 664, 665, 666, + 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 656, 514, 520, 515, 516, 517, 518, 519, + 0, 521, 0, 0, 0, 0, 0, 402, 0, 598, + 599, 679, 387, 492, 610, 338, 352, 355, 344, 364, + 0, 365, 340, 341, 346, 349, 350, 351, 356, 357, + 361, 367, 251, 212, 394, 403, 584, 315, 218, 219, + 220, 530, 531, 532, 533, 626, 627, 631, 207, 468, + 469, 470, 471, 295, 621, 312, 474, 473, 334, 335, + 382, 454, 546, 548, 559, 563, 565, 567, 573, 576, + 547, 549, 560, 564, 566, 568, 574, 577, 536, 538, + 540, 542, 555, 554, 551, 579, 580, 557, 562, 541, + 553, 558, 571, 578, 575, 535, 539, 543, 552, 570, + 569, 550, 561, 572, 556, 544, 537, 545, 0, 198, + 223, 371, 0, 460, 291, 657, 625, 490, 620, 208, + 225, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 200, 202, 211, 224, 234, 238, + 245, 264, 279, 281, 288, 301, 313, 321, 322, 325, + 331, 383, 390, 391, 392, 393, 413, 414, 415, 418, + 421, 422, 425, 427, 428, 431, 436, 440, 441, 442, + 444, 446, 448, 461, 466, 480, 481, 482, 483, 484, + 487, 488, 494, 495, 496, 497, 498, 506, 507, 522, + 593, 595, 612, 632, 639, 486, 388, 434, 458, 586, + 304, 305, 449, 450, 317, 318, 653, 654, 303, 607, + 640, 604, 652, 634, 443, 381, 0, 0, 384, 284, + 308, 323, 0, 624, 508, 229, 472, 293, 253, 0, + 0, 213, 248, 232, 262, 277, 280, 327, 395, 404, + 433, 439, 299, 274, 246, 465, 243, 491, 525, 526, + 527, 529, 399, 269, 438, 400, 0, 379, 582, 583, + 319, 0, 0, 0, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, + 0, 0, 0, 0, 273, 0, 0, 0, 0, 369, + 270, 0, 0, 206, 511, 0, 435, 0, 205, 0, + 493, 255, 380, 377, 590, 285, 276, 272, 252, 320, + 389, 432, 524, 426, 0, 373, 0, 0, 503, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 326, 250, + 328, 204, 417, 504, 289, 0, 0, 0, 0, 0, + 513, 196, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 247, 0, 0, 0, 354, 363, + 362, 342, 343, 345, 347, 353, 360, 366, 339, 348, + 0, 0, 616, 0, 0, 0, 268, 324, 275, 267, + 587, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 300, 0, 406, + 260, 0, 459, 0, 0, 0, 636, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 333, 199, 227, 0, + 0, 416, 467, 479, 0, 0, 0, 256, 0, 477, + 430, 611, 235, 287, 464, 437, 475, 445, 290, 0, + 0, 476, 375, 592, 455, 608, 637, 638, 266, 410, + 622, 528, 630, 655, 228, 263, 424, 512, 614, 500, + 401, 588, 589, 332, 499, 298, 203, 372, 643, 226, + 485, 374, 244, 233, 594, 619, 302, 254, 292, 462, + 650, 215, 523, 605, 241, 489, 0, 0, 658, 249, + 510, 617, 606, 217, 601, 509, 397, 329, 330, 216, + 0, 463, 271, 296, 0, 0, 261, 419, 596, 597, + 259, 659, 230, 629, 222, 0, 628, 412, 591, 602, + 398, 386, 221, 600, 396, 385, 337, 358, 359, 283, + 310, 452, 378, 453, 309, 311, 408, 407, 409, 209, + 615, 633, 0, 210, 0, 505, 618, 660, 457, 214, + 236, 237, 239, 0, 282, 286, 294, 297, 306, 307, + 316, 370, 423, 451, 447, 456, 0, 585, 609, 623, + 635, 641, 642, 644, 645, 646, 647, 648, 651, 649, + 411, 314, 501, 336, 376, 0, 0, 429, 478, 242, + 613, 502, 201, 0, 0, 0, 0, 257, 258, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, + 671, 672, 673, 674, 675, 676, 677, 678, 656, 514, + 520, 515, 516, 517, 518, 519, 0, 521, 0, 0, + 0, 0, 0, 402, 0, 598, 599, 679, 387, 492, + 610, 338, 352, 355, 344, 364, 0, 365, 340, 341, + 346, 349, 350, 351, 356, 357, 361, 367, 251, 212, + 394, 403, 584, 315, 218, 219, 220, 530, 531, 532, + 533, 626, 627, 631, 207, 468, 469, 470, 471, 295, + 621, 312, 474, 473, 334, 335, 382, 454, 546, 548, + 559, 563, 565, 567, 573, 576, 547, 549, 560, 564, + 566, 568, 574, 577, 536, 538, 540, 542, 555, 554, + 551, 579, 580, 557, 562, 541, 553, 558, 571, 578, + 575, 535, 539, 543, 552, 570, 569, 550, 561, 572, + 556, 544, 537, 545, 0, 198, 223, 371, 0, 460, + 291, 657, 625, 490, 620, 208, 225, 0, 265, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 202, 211, 224, 234, 238, 245, 264, 279, 281, + 288, 301, 313, 321, 322, 325, 331, 383, 390, 391, + 392, 393, 413, 414, 415, 418, 421, 422, 425, 427, + 428, 431, 436, 440, 441, 442, 444, 446, 448, 461, + 466, 480, 481, 482, 483, 484, 487, 488, 494, 495, + 496, 497, 498, 506, 507, 522, 593, 595, 612, 632, + 639, 486, 388, 434, 458, 586, 304, 305, 449, 450, + 317, 318, 653, 654, 303, 607, 640, 604, 652, 634, + 443, 381, 0, 0, 384, 284, 308, 323, 0, 624, + 508, 229, 472, 293, 253, 0, 0, 213, 248, 232, + 262, 277, 280, 327, 395, 404, 433, 439, 299, 274, + 246, 465, 243, 491, 525, 526, 527, 529, 399, 269, + 438, 0, 0, 379, 582, 583, 319, } var yyPact = [...]int{ - -1000, -1000, 4350, -1000, -549, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 5272, -1000, -551, -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, 2520, 2555, -1000, -1000, -1000, -1000, 2696, -1000, 1031, - 2117, -1000, 2474, 4989, -1000, 56250, 778, -1000, 53282, -420, - 897, 238, 36958, -1000, 193, -1000, 186, 54766, 189, -1000, - -1000, -1000, -1000, -420, 22860, 2334, 57, 55, 56250, -1000, - -1000, -1000, -1000, -373, 2641, 2087, -1000, 392, -1000, -1000, - -1000, -1000, -1000, -1000, 52540, -1000, 1119, -1000, -1000, 2482, - 2485, 2309, 941, 2399, -1000, 2569, 2087, -1000, 22860, 2632, - 2475, 22118, 22118, 456, -1000, -1000, 269, -1000, -1000, 31764, - 56250, 39926, 322, -1000, 2474, -1000, -1000, -1000, 211, -1000, - 342, 1987, -1000, 1971, -1000, 937, 914, 389, 473, 471, - 386, 385, 384, 368, 367, 363, 358, 355, 399, -1000, - 958, 958, -218, -220, 371, 769, 460, 460, 1035, 490, - 2427, 2379, -1000, -1000, 958, 958, 958, 339, 958, 958, - 958, 958, 311, 310, 958, 958, 958, 958, 958, 958, - 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, - 958, 917, 2474, 270, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 2469, 2576, -1000, -1000, -1000, -1000, 2667, -1000, 1033, + 2110, -1000, 2476, 5131, -1000, 55821, 518, -1000, 52837, -455, + 883, 238, 36425, -1000, 185, -1000, 159, 54329, 181, -1000, + -1000, -1000, -1000, -455, 22251, 2336, 37, 35, 55821, -1000, + -1000, -1000, -1000, -370, 2640, 2031, -1000, 400, -1000, -1000, + -1000, -1000, -1000, -1000, 52091, -1000, -1000, -1000, 1120, -1000, + -1000, 2480, 2501, 2332, 946, 2398, -1000, 2565, 2031, -1000, + 22251, 2620, 2438, 21505, 21505, 470, -1000, -1000, 275, -1000, + -1000, 31203, 55821, 39409, 909, -1000, 2476, -1000, -1000, -1000, + 193, -1000, 324, 1990, -1000, 1989, -1000, 913, 964, 387, + 469, 467, 386, 385, 383, 382, 367, 365, 363, 355, + 394, -1000, 962, 962, -241, -242, 1369, 796, 442, 442, + 1140, 483, 2444, 2443, -1000, -1000, 962, 962, 962, 360, + 962, 962, 962, 962, 301, 293, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 884, 2476, 276, -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, @@ -7470,68 +7435,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, 56250, 194, 56250, -1000, 828, 775, - -1000, -1000, -459, 1114, 1114, 101, 1114, 1114, 1114, 1114, - 183, 1043, 54, -1000, 182, 261, 168, 271, 1096, 304, - -1000, -1000, 257, 1096, 1834, -1000, 946, 266, 169, -1000, - 1114, 1114, -1000, 15416, 203, 15416, 15416, 265, 172, -1000, - 2464, -1000, -1000, -1000, -1000, -1000, 1344, -1000, -1000, -1000, - -1000, -37, 489, -1000, -1000, -1000, -1000, 54766, 51798, 283, - -1000, -1000, 780, 1851, 1393, 22860, 1315, 938, -1000, -1000, - 1434, 900, -1000, -1000, -1000, -1000, -1000, 809, -1000, 25086, - 25086, 25086, 25086, -1000, -1000, 1830, 51056, 1830, 1830, 25086, - 1830, 25086, 1830, 1830, 1830, 1830, 22860, 1830, 1830, 1830, - 1830, -1000, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, -1000, -1000, -1000, -1000, 1830, 826, 1830, 1830, 1830, - 1830, 1830, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1830, - 1830, 1830, 1830, 1830, 1830, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, -1000, -1000, - -1000, 1692, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1693, - 1513, 1500, 1498, -1000, 19892, 1830, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 55821, 252, 55821, -1000, 835, 517, -1000, -1000, -459, 1107, + 1107, 96, 1107, 1107, 1107, 1107, 172, 1028, 32, -1000, + 160, 294, 167, 277, 1099, 299, -1000, -1000, 265, 1099, + 1868, -1000, 951, 273, 158, -1000, 1107, 1107, -1000, 14767, + 206, 14767, 14767, 269, 147, -1000, 2457, -1000, -1000, -1000, + -1000, -1000, 1365, -1000, -1000, -1000, -1000, -39, 482, -1000, + -1000, -1000, -1000, 54329, 51345, 291, -1000, -1000, 33, 1892, + 1527, 22251, 1574, 944, -1000, -1000, 1428, 906, -1000, -1000, + -1000, -1000, -1000, 816, -1000, 24489, 24489, 24489, 24489, -1000, + -1000, 1998, 50599, 1998, 1998, 24489, 1998, 24489, 1998, 1998, + 1998, 1998, 22251, 1998, 1998, 1998, 1998, -1000, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, -1000, -1000, -1000, + -1000, 1998, 834, 1998, 1998, 1998, 1998, 1998, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1998, 1998, 1998, 1998, 1998, + 1998, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, -1000, -1000, -1000, 1684, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1652, 1611, 1609, 1588, -1000, + 19267, -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, -1000, -1000, -1000, 56250, -1000, 1830, - 216, 54766, 54766, 340, 1333, -1000, -1000, 2569, 2087, -1000, - 2641, 2620, 392, -1000, 3919, 2111, 1683, 1406, 2087, 1954, - 56250, -1000, 2005, -1000, -1000, -1000, -357, -364, 2232, 1455, - 1829, -1000, -1000, -1000, -1000, 1798, 22860, -1000, -1000, 2693, - -1000, 28796, 823, 2687, 50314, -1000, 456, 456, 1969, 421, - 13, -1000, -1000, -1000, -1000, 979, 36216, -1000, -1000, -1000, - -1000, -1000, 1884, 56250, -1000, -1000, 5043, 54766, -1000, 2107, - -1000, 1875, -1000, 2041, 22860, 2126, 768, 54766, 523, 516, - 510, 475, -62, -1000, -1000, -1000, -1000, -1000, -1000, 958, - 958, 958, -1000, 395, 2623, 4989, 5064, -1000, -1000, -1000, - 49572, 2102, 54766, -1000, 2088, -1000, 1039, 861, 864, 864, - 54766, -1000, -1000, 55508, 54766, 1037, 1033, 54766, 54766, 54766, - 54766, -1000, 48830, -1000, 48088, 47346, 1331, 54766, 46604, 45862, - 45120, 44378, 43636, -1000, 2609, -1000, 2204, -1000, -1000, -1000, - 55508, 54766, 54766, 55508, 54766, 55508, 56250, 54766, -1000, -1000, - 357, -1000, -1000, 1329, 1327, 1319, 958, 958, 1317, 1828, - 1823, 1816, 958, 958, 1305, 1800, 38442, 1780, 276, 1299, - 1296, 1294, 1293, 1775, 259, 1757, 1237, 1220, 1272, 54766, - 2083, 56250, -1000, 250, 1070, 434, 978, 2474, 2331, 1964, - 488, 767, 54766, 474, 474, 54766, -1000, 16164, 56250, 230, - -1000, 1744, 22860, -1000, 1117, 1096, 1096, -1000, -1000, -1000, - -1000, -1000, -1000, 1114, 56250, 1117, -1000, -1000, -1000, 1096, - 1114, 56250, 1114, 1114, 1114, 1114, 1096, 1096, 1096, 1114, - 56250, 56250, 56250, 56250, 56250, 56250, 56250, 56250, 56250, 15416, - 946, 1114, -460, -1000, 1742, -1000, -1000, -1000, 2230, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1998, -1000, -1000, -1000, 55821, -1000, 1998, 217, 54329, + 54329, 331, 1347, -1000, -1000, 2565, 2031, -1000, 2640, 2644, + 400, -1000, 3901, 1759, 1695, 1378, 2031, 1967, 55821, -1000, + 2015, 211, -1000, -1000, -1000, -309, -330, 2272, 1486, 1864, + -1000, -1000, -1000, -1000, 2347, 22251, -1000, -1000, 2662, -1000, + 28965, 833, 2658, 49853, -1000, 470, 470, 1986, 423, 9, + -1000, -1000, -1000, -1000, 982, 35679, -1000, -1000, -1000, -1000, + -1000, 1878, 55821, -1000, -1000, 5540, 54329, -1000, 2109, -1000, + 1862, -1000, 2072, 22251, 2125, 516, 54329, 513, 509, 499, + 463, -71, -1000, -1000, -1000, -1000, -1000, -1000, 962, 962, + 962, -1000, 393, 2614, 5131, 6483, -1000, -1000, -1000, 49107, + 2107, 54329, -1000, 2102, -1000, 1046, 842, 877, 877, 54329, + -1000, -1000, 55075, 54329, 1043, 1040, 54329, 54329, 54329, 54329, + -1000, 48361, -1000, 47615, 46869, 1346, 54329, 46123, 45377, 44631, + 43885, 43139, -1000, 2527, -1000, 2143, -1000, -1000, -1000, 55075, + 54329, 54329, 55075, 54329, 55075, 55821, 54329, -1000, -1000, 328, + -1000, -1000, 1343, 1340, 1338, 962, 962, 1337, 1857, 1852, + 1831, 962, 962, 1309, 1820, 37917, 1818, 266, 1303, 1296, + 1294, 1290, 1813, 205, 1809, 1288, 1272, 1280, 54329, 2093, + 55821, -1000, 260, 1006, 1015, 980, 2476, 2335, 1984, 480, + 515, 54329, 461, 461, 54329, -1000, 15519, 55821, 213, -1000, + 1770, 22251, -1000, 1102, 1099, 1099, -1000, -1000, -1000, -1000, + -1000, -1000, 1107, 55821, 1102, -1000, -1000, -1000, 1099, 1107, + 55821, 1107, 1107, 1107, 1107, 1099, 1099, 1099, 1107, 55821, + 55821, 55821, 55821, 55821, 55821, 55821, 55821, 55821, 14767, 951, + 1107, -460, -1000, 1757, -1000, -1000, -1000, 2231, -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, @@ -7546,337 +7511,339 @@ 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, -1000, -1000, -1000, 15416, - 15416, -1000, -1000, 2565, 2559, -1000, -1000, -1000, 1960, -1000, - 184, 17, 185, -1000, 42894, 535, 974, -1000, 535, -1000, - -1000, -1000, -1000, -1000, 1959, 42152, -1000, -461, -464, -467, - -469, -1000, -1000, -1000, -471, -473, -1000, -1000, -1000, 22860, - 22860, 22860, 22860, -257, -1000, 1217, 25086, 2491, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 22860, 247, 1131, 25086, 25086, - 25086, 25086, 25086, 25086, 25086, 26570, 25828, 25086, 25086, 25086, - 25086, 25086, 25086, -1000, -1000, 33990, 6271, 6271, 900, 900, - 900, 900, -1000, -174, 1958, 55508, -1000, -1000, -1000, 822, - 22860, 22860, 900, -1000, 1238, 2007, 19892, 22860, 22860, 22860, - 22860, 960, 1393, 55508, 22860, -1000, 1406, -1000, -1000, -1000, - -1000, 1234, -1000, -1000, 1081, 2376, 2376, 2376, 2376, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 2376, - 22860, 208, 208, 919, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 18408, 22860, 22860, 25086, 22860, 22860, 22860, 1406, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 1406, - 22860, 1221, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 17660, - 22860, 22860, 22860, 22860, 22860, -1000, -1000, -1000, -1000, -1000, - -1000, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 22860, 1406, - 22860, 22860, 22860, 22860, 22860, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1686, 1493, 1478, 22860, -1000, - 1957, -1000, -202, 31022, 22860, 1739, 2683, 2157, 54766, -1000, - -1000, -1000, -1000, 2569, -1000, 2569, 1686, 3881, 2277, 22118, - -1000, -1000, 3881, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1737, -1000, 56250, 1954, - 2545, 54766, -1000, -294, -1000, -295, 2272, 1730, 351, -1000, - 22860, 22860, 1953, -1000, 1399, 56250, -1000, -257, -1000, 41410, - -1000, -1000, 14668, 56250, 350, 56250, -1000, 30280, 40668, 306, - -1000, 13, 1933, -1000, 29, 1, 19150, 899, -1000, -1000, - -1000, 371, 27312, 1822, 899, 100, -1000, -1000, -1000, 2041, - -1000, 2041, 2041, 2041, 2041, 351, 351, 351, 351, -1000, - -1000, -1000, -1000, -1000, 2079, 2041, 2075, -1000, 2041, 2041, - 2041, 2041, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2073, - 2073, 2073, 2061, 2061, 2042, 2042, 447, -1000, 22860, 486, - 39926, 2537, 1270, 1538, 250, 475, 2144, 54766, 54766, 54766, - 56250, 989, -1000, 1445, 1412, 1398, -1000, -532, 1952, -1000, - -1000, 2617, -1000, -1000, 956, 1088, 1084, 1064, 54766, 214, - 335, -1000, 433, -1000, 39926, 54766, 1029, 864, 54766, -1000, - 54766, -1000, -1000, -1000, -1000, -1000, 54766, -1000, -1000, 1950, - -1000, 1927, 1106, 1083, 1098, 1080, 1950, -1000, -1000, -183, - 1950, -1000, 1950, -1000, 1950, -1000, 1950, -1000, 1950, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1001, 278, - -350, 54766, 214, 487, -1000, 485, 33990, -1000, -1000, -1000, - 33990, 33990, -1000, -1000, -1000, -1000, 1726, 1723, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 14767, 14767, + -1000, -1000, 2562, 2560, -1000, -1000, -1000, 1981, -1000, 175, + 4, 179, -1000, 42393, 493, 969, -1000, 493, -1000, -1000, + -1000, -1000, -1000, 1977, 41647, -1000, -463, -464, -468, -470, + -1000, -1000, -1000, -471, -477, -1000, -1000, -1000, 22251, 22251, + 22251, 22251, -276, -1000, 1426, 24489, 2456, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 22251, 1195, 1144, 24489, 24489, 24489, + 24489, 24489, 24489, 24489, 25981, 25235, 24489, 24489, 24489, 24489, + 24489, 24489, -1000, -1000, 33441, 5242, 5242, 906, 906, 906, + 906, -1000, -181, 1973, 55075, -1000, -1000, -1000, 832, 22251, + 22251, 906, -1000, 1196, 1029, 19267, 22251, 22251, 22251, 22251, + 990, 1527, 55075, 22251, -1000, 1378, -1000, -1000, -1000, -1000, + 1200, -1000, -1000, 1091, 2403, 2403, 2403, 2403, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 2403, 22251, + 151, 151, 961, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 17775, 22251, 22251, 24489, 22251, 22251, 22251, 1378, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 1378, 22251, + 1199, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 17023, 22251, + 22251, 22251, 22251, 22251, -1000, -1000, -1000, -1000, -1000, -1000, + 22251, 22251, 22251, 22251, 22251, 22251, 22251, 22251, 1378, 22251, + 22251, 22251, 22251, 22251, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1764, 1721, 1554, 1998, 22251, -1000, + 1972, -1000, -183, 30457, 22251, 1755, 2651, 2147, 54329, -1000, + -1000, -1000, -1000, 2565, -1000, 2565, 1764, 3686, 2279, 21505, + -1000, -1000, 3686, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 1783, -1000, 55821, 1967, + 2544, 54329, -1000, 1958, -1000, -1000, 1998, -1000, -315, -1000, + -343, 2265, 1752, 371, -1000, 22251, 22251, 1951, -1000, 1409, + 55821, -1000, -276, -1000, 40901, -1000, -1000, 14015, 55821, 337, + 55821, -1000, 29711, 40155, 303, -1000, 9, 1923, -1000, 11, + -15, 18521, 901, -1000, -1000, -1000, 1369, 26727, 1879, 901, + 85, -1000, -1000, -1000, 2072, -1000, 2072, 2072, 2072, 2072, + 371, 371, 371, 371, -1000, -1000, -1000, -1000, -1000, 2092, + 2072, 2091, -1000, 2072, 2072, 2072, 2072, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -520, 56250, -1000, - 236, 971, 268, 376, 291, 56250, 405, 2423, 2413, 2403, - 2396, 2391, 2373, 2366, 242, 298, 56250, 56250, 474, 2206, - 56250, 2522, 56250, -1000, -1000, -1000, -1000, -1000, 1716, 1708, - -1000, 1393, 56250, -1000, -1000, 1114, 1114, -1000, -1000, 56250, - 1114, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1114, + -1000, -1000, -1000, -1000, 2089, 2089, 2089, 2088, 2088, 2074, + 2074, 437, -1000, 22251, 384, 39409, 2517, 1279, 1681, 260, + 463, 2144, 54329, 54329, 54329, 55821, 1005, -1000, 1476, 1469, + 1425, -1000, -533, 1950, -1000, -1000, 2606, -1000, -1000, 1105, + 1087, 1082, 1138, 54329, 229, 323, -1000, 429, -1000, 39409, + 54329, 1038, 877, 54329, -1000, 54329, -1000, -1000, -1000, -1000, + -1000, 54329, -1000, -1000, 1949, -1000, 1959, 1103, 1081, 1088, + 1065, 1949, -1000, -1000, -189, 1949, -1000, 1949, -1000, 1949, + -1000, 1949, -1000, 1949, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 963, 336, -384, 54329, 229, 475, -1000, + 473, 33441, -1000, -1000, -1000, 33441, 33441, -1000, -1000, -1000, + -1000, 1741, 1737, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 56250, -1000, -1000, -1000, -1000, - 1702, -1000, 56250, -37, 177, -1000, -1000, 54766, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -114, -1000, 854, - 26, 393, -1000, -1000, -1000, -1000, -1000, 2550, -1000, 1393, - 1021, 1010, -1000, 1830, -1000, -1000, 1233, -1000, -1000, -1000, - -1000, -1000, 1830, 1830, 1830, -1000, -1000, -1000, -1000, -1000, - 247, 25086, 25086, 25086, 1782, 777, 1891, 1812, 1474, 1231, - 1231, 976, 25086, 976, 25086, 918, 918, 918, 918, 918, - -1000, -1000, -1000, -1000, -1000, -1000, 1692, -1000, 1667, -1000, - 1830, 55508, 1827, 17660, 1747, 1599, 1406, 932, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3935, 1406, - 1851, 1406, 1674, 3902, 1026, -1000, 22860, 1406, 3610, -1000, - -1000, 1406, 1406, 22860, -1000, -1000, 22860, 22860, 22860, 22860, - 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, - 22860, 1538, 1947, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -522, 55821, -1000, 254, 968, 304, 296, 308, + 55821, 390, 2432, 2430, 2426, 2408, 2401, 2395, 2383, 239, + 288, 55821, 55821, 461, 2208, 55821, 2507, 55821, -1000, -1000, + -1000, -1000, -1000, 1733, 1704, -1000, 1527, 55821, -1000, -1000, + 1107, 1107, -1000, -1000, 55821, 1107, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1107, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 1938, 2669, 1558, 1538, 1538, 1538, 1538, 3587, 1538, - 1538, 22860, 1358, -1000, -1000, -1000, 1419, 3583, 1684, 3572, - 1538, 1538, -1000, 1538, 3541, 3536, 1406, 2928, 2820, 1538, - 1538, 1538, 1538, 1538, 2792, 2778, 1538, 1538, 2705, 1538, - 3522, 1538, 2698, 2681, 2677, 2633, 2611, 2603, 2594, 2570, - 2561, 2539, 2533, 2523, 2509, 2492, 2458, 2448, 2444, 2407, - 1538, 1538, 1538, 3508, 1538, 3489, 1538, 3485, 1538, 1538, - 3474, 2394, 2364, 1406, 1934, -1000, 3469, 1538, 3457, 3453, - 3446, 2354, 3427, 3422, 3418, 1538, 1538, 1538, 2339, 3413, - 3407, 3395, 3391, 3374, 3369, 3364, 3355, 3343, 1538, 1478, - 1478, 1478, 1478, 1478, 3253, -259, 1538, 1406, -1000, -1000, - -1000, -1000, -1000, 3092, 2333, 3042, 3030, 3011, 3003, 1406, - 1830, 821, -1000, -1000, 1478, 1406, 1406, 1478, 1478, 2995, - 2963, 2957, 2953, 2933, 2834, 1538, 1538, -1000, 1538, 2810, - 2800, 2303, 2290, 1406, -1000, 1478, 56250, -1000, -451, -1000, - -8, 954, 1830, -1000, 38442, 1406, -1000, 4349, -1000, 1168, - -1000, -1000, -1000, -1000, -1000, 35474, 1879, -1000, -1000, -1000, - -1000, 1830, 1762, -1000, -1000, -1000, -1000, 351, 73, 34732, - 890, 890, 123, 1393, 1393, 22860, -1000, -1000, -1000, -1000, - -1000, -1000, 820, 2642, 404, 1830, -1000, 1948, 3576, -1000, - -1000, -1000, 2544, 28054, -1000, -1000, 1830, 1830, 56250, 1939, - 1745, -1000, 819, -1000, 1320, 1933, 13, 24, -1000, -1000, - -1000, -1000, 1393, -1000, 1378, 353, 346, -1000, 437, -1000, - -1000, -1000, -1000, 2343, 81, -1000, -1000, -1000, 912, 351, - -1000, -1000, -1000, -1000, -1000, -1000, 1664, -1000, 1664, -1000, - -1000, -1000, -1000, -1000, 1268, -1000, -1000, -1000, -1000, 1266, - -1000, -1000, 1256, -1000, -1000, 2877, 2183, 486, -1000, -1000, - 958, 1655, -1000, -1000, 2356, 958, 958, 54766, -1000, -1000, - 1783, 2537, 236, 56250, 2203, -1000, 2144, 2144, 2144, -1000, - 2497, -1000, -1000, -1000, -1000, -1000, -1000, -522, 174, 609, - -1000, -1000, -1000, 1389, 54766, 1721, -1000, 224, -1000, 1779, - -1000, 54766, -1000, 1713, 2053, 54766, 54766, -1000, -1000, -1000, - 54766, 1830, -1000, -1000, -1000, -1000, 760, 2471, 319, -1000, - -1000, -283, -1000, -1000, 214, 224, 55508, 54766, 899, -1000, - -1000, -1000, -1000, -1000, -523, 1690, 506, 228, 328, 56250, - 56250, 56250, 56250, 56250, 56250, 800, -1000, -1000, 39, -1000, - -1000, 202, -1000, -1000, 1623, -1000, -1000, -1000, -1000, 202, - -1000, -1000, -1000, -1000, -1000, 275, 478, -1000, 56250, 56250, - 964, -1000, -1000, -1000, -1000, -1000, 1096, -1000, -1000, 1096, + 55821, -1000, -1000, -1000, -1000, 1689, -1000, 55821, -39, 153, + -1000, -1000, 54329, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -117, -1000, 327, 2, 419, -1000, -1000, -1000, + -1000, -1000, 2553, -1000, 1527, 1009, 1020, -1000, 1998, -1000, + -1000, 1108, -1000, -1000, -1000, -1000, -1000, 1998, 1998, 1998, + -1000, -1000, -1000, -1000, -1000, 1195, 24489, 24489, 24489, 1509, + 799, 1412, 924, 1454, 1443, 1443, 955, 24489, 955, 24489, + 910, 910, 910, 910, 910, -1000, -1000, -1000, -1000, -1000, + -1000, 1684, -1000, 1682, -1000, 1998, 55075, 1844, 17023, 2023, + 1371, 1378, 933, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 2457, 56250, 20, -490, -1000, -486, 22860, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1666, 749, 1891, 25086, - 25086, 2007, 2007, 25086, -1000, -1000, -1000, 1076, 1076, 33990, - -1000, 25086, 22860, -1000, -1000, 22860, 22860, 22860, 981, -1000, - 22860, 1181, -1000, 22860, -1000, -259, 1478, 1538, 1538, 1538, - 1538, -259, -259, -259, -259, -259, -259, -259, -259, -259, - -259, 1908, -1000, 22860, 22860, 22860, 1406, 334, -1000, -1000, - -1000, -259, 22860, -1000, -1000, 2666, -1000, 22860, -1000, 33990, - 22860, 22860, 22860, -1000, -1000, -1000, 22860, 22860, -1000, -1000, - 22860, -1000, 22860, -1000, -1000, -1000, -1000, -1000, -1000, 22860, - -1000, 22860, -1000, -1000, -1000, 22860, -1000, 22860, -1000, -1000, - 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, - 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, - 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, - 22860, -1000, 22860, -1000, 22860, -1000, -1000, -1000, 22860, -1000, - 22860, -1000, 22860, -1000, -1000, 22860, -1000, 22860, -1000, 22860, - -1000, 22860, 22860, -1000, 22860, 22860, 22860, -1000, 22860, 22860, - 22860, 22860, -1000, -1000, -1000, -1000, 22860, 22860, 22860, 22860, - 22860, 22860, 22860, 22860, 22860, 22860, -1000, -1000, -1000, -1000, - -1000, -1000, 22860, -1000, 39926, 47, -259, 1221, 47, 1221, - 24344, 832, 507, 23602, -1000, 22860, 16912, -1000, -1000, -1000, - -1000, -1000, 22860, 22860, 22860, 22860, 22860, 22860, -1000, -1000, - -1000, 22860, 22860, -1000, 22860, -1000, 22860, -1000, -1000, -1000, - -1000, -1000, 954, -1000, 455, 453, 864, 54766, -1000, -1000, - -1000, -1000, 1930, -1000, 2564, -1000, 2285, 2284, 2659, 2642, - 22118, -1000, 30280, -1000, -1000, 54766, -419, -1000, 2326, 2476, - 890, 890, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 13920, - 2569, 22860, 2201, 55508, 223, -1000, 29538, 54766, 55508, 30280, - 30280, 30280, 30280, 30280, -1000, 2242, 2235, -1000, 2254, 2228, - 2313, 56250, -1000, 1686, 1688, -1000, 22860, 32506, 1935, 30280, - -1000, -1000, 30280, 56250, 13172, -1000, -1000, 6, -7, -1000, - -1000, -1000, -1000, 371, -1000, -1000, 1082, 2543, 2338, -1000, - -1000, -1000, -1000, -1000, 1682, -1000, 1676, 1928, 1671, 1662, - 278, -1000, 2067, 2451, 958, 958, -1000, 1254, -1000, 1238, - 1614, 1586, -1000, -1000, -1000, 496, -1000, 56250, 2200, 2195, - 2194, -1000, -540, 1253, 2052, 2012, 22860, 2051, 2615, 1913, - 54766, -1000, -1000, 55508, -1000, 197, -1000, 486, 54766, -1000, - -1000, -1000, 335, 56250, -1000, 7068, -1000, -1000, -1000, 224, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 56250, 233, -1000, - 2047, 1343, -1000, -1000, 2140, -1000, -1000, -1000, -1000, -1000, - 213, 201, 1583, 199, 1547, -1000, 199, -1000, 56250, 928, - 2183, 56250, -1000, -1000, -1000, 1114, 1114, -1000, -1000, 2449, - -1000, 1238, 1538, 25086, 25086, -1000, 900, -1000, -1000, 435, - -229, 2041, 2041, -1000, 2041, 2042, -1000, 2041, 171, 2041, - 154, 2041, -1000, -1000, 1406, 1406, -1000, 1478, 2286, 1439, - 2796, -1000, 1393, 22860, 2715, -1000, -1000, -259, -259, -259, - -259, -259, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -69, 2689, 2637, 1538, -1000, 2039, 2036, -1000, - 1538, 22860, 1538, 1406, 2278, 1538, 1538, 1538, 1538, 1538, - 1538, 1538, 1538, 1538, 1538, 1538, 1538, 2266, 2257, 2249, - 2196, 2175, 2171, 2167, 2163, 2158, 2149, 2145, 2128, 2084, - 2080, 2076, 2062, 1538, 1538, 2058, 1538, 2054, 2048, -1000, - 1393, 1478, 2628, 1478, 1538, 1538, 2527, 337, 1538, 1651, - 1651, 1651, 1651, 1651, 1478, 1478, 1478, 1478, 1538, 54766, - -1000, -259, -1000, -1000, -307, -309, -1000, 1406, -259, 1926, - 25086, 1538, 25086, 25086, 25086, 1538, 1406, -1000, 2043, 2010, - 2270, 1940, 1538, 1832, 1538, 1538, 1538, 1821, -1000, 2535, - 1830, 2535, 1830, 2535, 1647, 1168, 56250, -1000, -1000, -1000, - -1000, 2642, 2639, -1000, 1914, -1000, 73, 639, -1000, 2311, - 2476, -1000, 2610, 2306, 2598, -1000, -1000, -1000, -1000, -1000, - 1393, -1000, 2479, 1916, -1000, 963, 1907, -1000, -1000, 21376, - 1649, 2281, 817, 1647, 1923, 3576, 2136, 2190, 3359, -1000, - -1000, -1000, -1000, 2231, -1000, 2063, -1000, -1000, 2005, -1000, - 1790, 350, 30280, 1877, 1877, -1000, 816, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1100, 7068, 2704, -1000, 1544, -1000, - 1366, 195, 1240, -1000, -1000, 958, 958, -1000, 1028, 1020, - -1000, 56250, 2031, -1000, 351, 1529, 351, 1225, -1000, -1000, - 1215, -1000, -1000, -1000, -1000, 1994, 2562, -1000, -1000, -1000, - -1000, 56250, -1000, 56250, 56250, 56250, 2029, 2595, -1000, 22860, - 2015, 962, 2253, 54766, 54766, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 427, 958, -503, 297, - 294, 958, 958, 958, -541, -1000, -1000, 1639, 1637, -1000, - -205, -1000, 22860, -1000, -1000, -1000, -1000, -1000, 1249, 1249, - 1513, 1500, 1498, -1000, 2005, -1000, -1000, -1000, 1722, -1000, - -1000, -186, 54766, 54766, 54766, 54766, -1000, -1000, -1000, 1187, + -1000, -1000, -1000, 3541, 1378, 1892, 1378, 2206, 3526, 997, + -1000, 22251, 1378, 3516, -1000, -1000, 1378, 1378, 22251, -1000, + -1000, 22251, 22251, 22251, 22251, 1681, 1681, 1681, 1681, 1681, + 1681, 1681, 1681, 1681, 1681, 22251, 1681, 1945, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 900, 1406, 375, -188, 1406, -1000, -1000, 351, + -1000, -1000, -1000, -1000, -1000, -1000, 1935, 2649, 2008, 1681, + 1681, 1681, 1681, 3508, 1681, 1681, 22251, 1308, -1000, -1000, + -1000, 1562, 3504, 1367, 3496, 1681, 1681, -1000, 1681, 3491, + 3485, 1378, 2671, 2666, 1681, 1681, 1681, 1681, 1681, 2650, + 2632, 1681, 1681, 2581, 1681, 3461, 1681, 2564, 2556, 2551, + 2542, 2534, 2526, 2479, 2454, 2448, 2427, 2418, 2411, 2373, + 2338, 2331, 2322, 2308, 2304, 1681, 1681, 1681, 3450, 1681, + 3446, 1681, 3442, 1681, 1681, 3433, 2300, 2295, 1378, 1932, + -1000, 3418, 1681, 3414, 3410, 3405, 2270, 3398, 3388, 3384, + 1681, 1681, 1681, 2261, 3371, 3363, 3109, 3102, 3097, 3058, + 3048, 3044, 3028, 1681, 1554, 1554, 1554, 1554, 1554, 3024, + -279, 1681, 1378, -1000, -1000, -1000, -1000, -1000, 2996, 2256, + 2992, 2981, 2976, 2955, 1378, 1998, 831, -1000, -1000, 1554, + 1378, 1378, 1554, 1554, 2920, 2894, 2890, 2882, 2816, 2796, + 1681, 1681, -1000, 1681, 2774, 2762, 2234, 2190, 1378, -1000, + 1554, 55821, -1000, -454, -1000, -12, 912, 1998, -1000, 37917, + 1378, -1000, 4152, -1000, 1353, -1000, -1000, -1000, -1000, -1000, + 34933, 1828, -1000, -1000, -1000, -1000, 1998, 1802, -1000, -494, + 20759, -1000, -1000, -1000, 371, 56, 34187, 882, 882, 111, + 1527, 1527, 22251, -1000, -1000, -1000, -1000, -1000, -1000, 829, + 2639, 438, 1998, -1000, 1944, 2988, -1000, -1000, -1000, 2541, + 27473, -1000, -1000, 1998, 1998, 55821, 1839, 1799, -1000, 825, + -1000, 1370, 1923, 9, -9, -1000, -1000, -1000, -1000, 1527, + -1000, 1422, 353, 351, -1000, 462, -1000, -1000, -1000, -1000, + 2357, 75, -1000, -1000, -1000, 373, 371, -1000, -1000, -1000, + -1000, -1000, -1000, 1678, -1000, 1678, -1000, -1000, -1000, -1000, + -1000, 1277, -1000, -1000, -1000, -1000, 1274, -1000, -1000, 1271, + -1000, -1000, 2692, 2171, 384, -1000, -1000, 962, 1667, -1000, + -1000, 2375, 962, 962, 54329, -1000, -1000, 1829, 2517, 254, + 55821, 2207, -1000, 2144, 2144, 2144, -1000, 2503, -1000, -1000, + -1000, -1000, -1000, -1000, -526, 176, 364, -1000, -1000, -1000, + 5096, 54329, 1794, -1000, 226, -1000, 1765, -1000, 54329, -1000, + 1792, 2087, 54329, 54329, -1000, -1000, -1000, 54329, 1998, -1000, + -1000, -1000, -1000, 504, 2475, 332, -1000, -1000, -301, -1000, + -1000, 229, 226, 55075, 54329, 901, -1000, -1000, -1000, -1000, + -1000, -527, 1787, 490, 231, 334, 55821, 55821, 55821, 55821, + 55821, 55821, 791, -1000, -1000, 18, -1000, -1000, 203, -1000, + -1000, 1664, -1000, -1000, -1000, -1000, 203, -1000, -1000, -1000, + -1000, -1000, 274, 472, -1000, 55821, 55821, 931, -1000, -1000, + -1000, -1000, -1000, 1099, -1000, -1000, 1099, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2453, + 55821, -1, -491, -1000, -488, 22251, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1331, 506, 1412, 24489, 24489, 1029, 1029, + 24489, -1000, -1000, -1000, 996, 996, 33441, -1000, 24489, 22251, + -1000, -1000, 22251, 22251, 22251, 985, -1000, 22251, 1291, -1000, + 22251, -1000, -279, 1554, 1681, 1681, 1681, 1681, -279, -279, + -279, -279, -279, -279, -279, -279, -279, -279, 1926, -1000, + 22251, 22251, 22251, 1378, 333, -1000, -1000, -1000, -279, 22251, + -1000, -1000, 2645, -1000, 22251, -1000, 33441, 22251, 22251, 22251, + -1000, -1000, -1000, 22251, 22251, -1000, -1000, 22251, -1000, 22251, + -1000, -1000, -1000, -1000, -1000, -1000, 22251, -1000, 22251, -1000, + -1000, -1000, 22251, -1000, 22251, -1000, -1000, 22251, -1000, 22251, + -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, + -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, + -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, + -1000, 22251, -1000, -1000, -1000, 22251, -1000, 22251, -1000, 22251, + -1000, -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, 22251, + -1000, 22251, 22251, 22251, -1000, 22251, 22251, 22251, 22251, -1000, + -1000, -1000, -1000, 22251, 22251, 22251, 22251, 22251, 22251, 22251, + 22251, 22251, 22251, -1000, -1000, -1000, -1000, -1000, -1000, 22251, + -1000, 39409, 8, -279, 1199, 8, 1199, 23743, 837, 817, + 22997, -1000, 22251, 16271, -1000, -1000, -1000, -1000, -1000, 22251, + 22251, 22251, 22251, 22251, 22251, -1000, -1000, -1000, 22251, 22251, + -1000, 22251, -1000, 22251, -1000, -1000, -1000, -1000, -1000, 912, + -1000, 471, 446, 877, 54329, -1000, -1000, -1000, -1000, 1922, + -1000, 2552, -1000, 2301, 2292, 2641, 2639, 21505, -1000, 29711, + -1000, -1000, 54329, -1000, -1000, -443, -1000, 2328, 2340, 882, + 882, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 13263, 2565, + 22251, 2204, 55075, 1998, -1000, 28219, 54329, 55075, 29711, 29711, + 29711, 29711, 29711, -1000, 2222, 2220, -1000, 2249, 2248, 2296, + 55821, -1000, 1764, 1781, -1000, 22251, 31949, 1886, 29711, -1000, + -1000, 29711, 55821, 12511, -1000, -1000, -5, -20, -1000, -1000, + -1000, -1000, 1369, -1000, -1000, 1213, 2535, 2351, -1000, -1000, + -1000, -1000, -1000, 1777, -1000, 1748, 1921, 1732, 1730, 336, + -1000, 2118, 2449, 962, 962, -1000, 1263, -1000, 1196, 1661, + 1655, -1000, -1000, -1000, 489, -1000, 55821, 2199, 2191, 2186, + -1000, -544, 1255, 2085, 2116, 22251, 2078, 2604, 1905, 54329, + -1000, -1000, 55075, -1000, 278, -1000, 384, 54329, -1000, -1000, + -1000, 323, 55821, -1000, 9274, -1000, -1000, -1000, 226, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 55821, 241, -1000, 2076, + 1361, -1000, -1000, 2131, -1000, -1000, -1000, -1000, -1000, 208, + 189, 1634, 196, 1622, -1000, 196, -1000, 55821, 923, 2171, + 55821, -1000, -1000, -1000, 1107, 1107, -1000, -1000, 2440, -1000, + 1196, 1681, 24489, 24489, -1000, 906, -1000, -1000, 503, -256, + 2072, 2072, -1000, 2072, 2074, -1000, 2072, 134, 2072, 127, + 2072, -1000, -1000, 1378, 1378, -1000, 1554, 2185, 1383, 2727, + -1000, 1527, 22251, 2719, -1000, -1000, -279, -279, -279, -279, + -279, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -78, 2712, 2706, 1681, -1000, 2070, 2062, -1000, 1681, + 22251, 1681, 1378, 2166, 1681, 1681, 1681, 1681, 1681, 1681, + 1681, 1681, 1681, 1681, 1681, 1681, 2162, 2158, 2154, 2150, + 2145, 2135, 2124, 2117, 2063, 2056, 2045, 2040, 2019, 1995, + 1991, 1979, 1681, 1681, 1974, 1681, 1969, 1928, -1000, 1527, + 1554, 2687, 1554, 1681, 1681, 2637, 330, 1681, 1728, 1728, + 1728, 1728, 1728, 1554, 1554, 1554, 1554, 1681, 54329, -1000, + -279, -1000, -1000, -373, -379, -1000, 1378, -279, 1913, 24489, + 1681, 24489, 24489, 24489, 1681, 1378, -1000, 1897, 1860, 2589, + 1855, 1681, 2378, 1681, 1681, 1681, 1812, -1000, 2536, 1998, + 2536, 1998, 2536, 1712, 1353, 55821, -1000, -1000, -1000, -1000, + 2639, 2629, -1000, 1906, -1000, 56, 616, -1000, 2360, 2340, + -1000, 2603, 2320, 2602, -1000, -1000, -1000, -1000, -1000, 1527, + -1000, 2478, 1896, -1000, 967, 1925, -1000, -1000, 20759, 1717, + 2284, 803, 1712, 1966, 2988, 2140, 2179, 3393, -1000, -1000, + -1000, -1000, 2168, -1000, 2164, -1000, -1000, 2015, -1000, 2366, + 337, 29711, 1965, 1965, -1000, 801, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1100, 9274, 2678, -1000, 1619, -1000, 1360, + 195, 1253, -1000, -1000, 962, 962, -1000, 1035, 1034, -1000, + 55821, 2060, -1000, 371, 1617, 371, 1249, -1000, -1000, 1244, + -1000, -1000, -1000, -1000, 2099, 2350, -1000, -1000, -1000, -1000, + 55821, -1000, 55821, 55821, 55821, 2050, 2601, -1000, 22251, 2048, + 965, 2617, 54329, 54329, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 427, 962, -505, 286, 282, + 962, 962, 962, -545, -1000, -1000, 1703, 1701, -1000, -190, + -1000, 22251, -1000, -1000, -1000, -1000, -1000, 1305, 1305, 1611, + 1609, 1588, -1000, 2015, -1000, -1000, -1000, 1696, -1000, -1000, + -203, 54329, 54329, 54329, 54329, -1000, -1000, -1000, 1209, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 22860, -1000, 22860, -1000, 22860, 1393, 22860, -1000, -1000, -1000, - -1000, -1000, 2569, 1489, 22860, 22860, -1000, 1211, 1209, -259, - 1538, -1000, -1000, -1000, 22860, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 22860, -1000, - 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, - 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, - 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, 22860, -1000, - -1000, 22860, -1000, -1000, -1000, 22860, -1000, 22860, -1000, 22860, - -1000, -1000, -1000, 22860, 264, 1076, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1406, 347, -1000, - -1000, -1000, 2650, -1000, 1406, 22860, 2007, -1000, 2007, 2007, - 2007, -1000, -1000, -1000, 22860, -1000, 22860, 22860, -1000, 22860, - -1000, 22860, -1000, -1000, -1000, -1000, 22860, 1830, 2374, 39184, - 1830, 39184, 1830, 32506, -1000, -1000, 2639, 2596, 2593, 2300, - 2312, 2312, 2311, -1000, 2589, 2587, -1000, 1472, 2585, 1458, - 1006, -1000, 55508, 22860, -1000, 223, 38442, -1000, 403, 54766, - 223, 54766, -1000, 2634, -1000, -1000, 22860, 2014, -1000, 22860, - -1000, -1000, -1000, -1000, 6271, 2642, 1877, -1000, -1000, 922, - -1000, 22860, -1000, 11485, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1453, 1446, -1000, -1000, 2006, 22860, -1000, -1000, - -1000, 1663, 1652, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2005, -1000, -1000, -1000, -1000, 335, -527, 2224, 54766, - 1206, -1000, 1632, 1913, 288, 223, 1432, 958, 958, 958, - 1161, 1152, 38442, 1605, -1000, 54766, 364, -1000, 335, -1000, - -222, -223, 1538, -1000, -1000, 2530, -1000, -1000, 16912, -1000, - -1000, 2003, 2141, -1000, -1000, -1000, -1000, 2264, -179, -200, - -1000, -1000, 1538, 1538, 1538, 1405, 1406, -1000, 1538, 1538, - 1633, 1543, -1000, -1000, 1538, 1538, 1538, 1538, 1538, 1538, - 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, - 1538, 1538, 1538, 1538, 1478, 1778, -1000, 264, 1406, 2184, - -1000, -1000, 6271, -1000, -1000, 2634, 2579, 47, -1000, -1000, - 222, 47, 1393, 1032, 1406, 1406, 1032, 1760, 1538, 1660, - 1642, 1538, 1538, 33248, -1000, 2572, 2571, 1542, -1000, -1000, - 39184, 1542, 39184, 954, 2596, -270, 22860, 22860, 2297, 1164, - -1000, -1000, -1000, -1000, 1402, 1390, -1000, 1377, -1000, 2699, - -1000, 1393, -1000, 1830, 223, -1000, 808, 1907, -1000, 2569, - 1393, 54766, 1393, 75, 2634, -1000, 1538, -1000, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, - 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, -1000, - -1000, 54766, 2180, -1000, -1000, 2529, 1554, 166, -1000, 1475, - 1913, -1000, -1000, 221, -1000, 22860, -1000, 38442, 1374, 1360, - -1000, -1000, -1000, -1000, -541, -1000, -1000, -1000, -1000, -1000, - -1000, 392, 1888, -1000, 957, 54766, 56250, -1000, 2188, -1000, - -1000, -1000, -1000, 22860, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 906, 1378, 376, -205, 1378, -1000, -1000, 371, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 22251, + -1000, 22251, -1000, 22251, 1527, 22251, -1000, -1000, -1000, -1000, + -1000, 2565, 1581, 22251, 22251, -1000, 1226, 1204, -279, 1681, + -1000, -1000, -1000, 22251, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 22251, -1000, 22251, + -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, + -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, + -1000, 22251, -1000, 22251, -1000, 22251, -1000, 22251, -1000, -1000, + 22251, -1000, -1000, -1000, 22251, -1000, 22251, -1000, 22251, -1000, + -1000, -1000, 22251, 233, 996, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 1378, 329, -1000, -1000, + -1000, 2638, -1000, 1378, 22251, 1029, -1000, 1029, 1029, 1029, + -1000, -1000, -1000, 22251, -1000, 22251, 22251, -1000, 22251, -1000, + 22251, -1000, -1000, -1000, -1000, 22251, 1998, 2468, 38663, 1998, + 38663, 1998, 31949, -1000, -1000, 2629, 2591, 2597, 2309, 2311, + 2311, 2360, -1000, 2594, 2583, -1000, 1564, 2582, 1555, 1027, + -1000, 55075, 22251, -1000, 1998, 37917, -1000, 426, 54329, 1998, + 54329, -1000, 2577, -1000, -1000, 22251, 2036, -1000, 22251, -1000, + -1000, -1000, -1000, 5242, 2639, 1965, -1000, -1000, 916, -1000, + 22251, -1000, 10482, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1549, 1523, -1000, -1000, 2022, 22251, -1000, -1000, -1000, + 1629, 1563, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 2015, -1000, -1000, -1000, -1000, 323, -538, 2223, 54329, 1153, + -1000, 1699, 1905, 309, 1998, 1521, 962, 962, 962, 1139, + 1132, 37917, 1693, -1000, 54329, 350, -1000, 323, -1000, -250, + -251, 1681, -1000, -1000, 2524, -1000, -1000, 16271, -1000, -1000, + 2013, 2137, -1000, -1000, -1000, -1000, 2188, -187, -221, -1000, + -1000, 1681, 1681, 1681, 1189, 1378, -1000, 1681, 1681, 1548, + 1410, -1000, -1000, 1681, 1681, 1681, 1681, 1681, 1681, 1681, + 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, + 1681, 1681, 1681, 1554, 1808, -1000, 233, 1378, 2172, -1000, + -1000, 5242, -1000, -1000, 2577, 2579, 8, -1000, -1000, 221, + 8, 1527, 1019, 1378, 1378, 1019, 1790, 1681, 1775, 1726, + 1681, 1681, 32695, -1000, 2574, 2571, 1671, -1000, -1000, 38663, + 1671, 38663, 912, 2591, -288, 22251, 22251, 2305, 1207, -1000, + -1000, -1000, -1000, 1519, 1488, -1000, 1465, -1000, 2677, -1000, + 1527, -1000, 1998, 1998, -1000, 795, 1925, -1000, 2565, 1527, + 54329, 1527, 55, 2577, -1000, 1681, -1000, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, + 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, -1000, -1000, + 54329, 2181, -1000, -1000, 2513, 1688, 163, -1000, 1384, 1905, + -1000, -1000, 892, -1000, 22251, -1000, 37917, 1436, 1385, -1000, + -1000, -1000, -1000, -545, -1000, -1000, -1000, -1000, -1000, -1000, + 400, 1901, -1000, 960, 54329, 55821, -1000, 2161, -1000, -1000, + -1000, -1000, 22251, -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, 22860, -1000, 1406, 2181, -1000, -375, -1000, -504, 22860, - -259, -1000, -1000, -259, -1000, -1000, -1000, -1000, -1000, 22860, - -1000, -1000, 22860, -1000, 22860, -1000, -1000, 1542, -1000, -1000, - -1000, 37700, -1000, 1542, -1000, 1542, -1000, -270, -1000, 1882, - -1000, 54766, 1393, 345, -1000, 1162, -1000, -1000, -1000, -1000, - -1000, 55508, 54766, 1907, 54766, -1000, -1000, 1508, 1406, 1830, - 2569, -1000, 1482, -1000, 392, -1000, 2002, 2012, -1000, -1000, - -1000, 20634, -1000, -1000, -1000, -1000, -1000, 249, -185, 16912, - 12424, 1480, -1000, -184, 1538, 1478, -1000, -479, -1000, -1000, - -1000, -1000, 279, -1000, -1000, 1851, -1000, -1000, 1621, 1527, - 1444, -1000, -1000, -1000, -1000, -1000, -1000, -270, -1000, -1000, - 2525, -1000, -226, -1000, -1000, 1367, 1442, -1000, -1000, -1000, - 32506, 54024, -1000, -171, 293, -185, 22860, 1995, 1406, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -52, -1000, -1000, - 799, -1000, -1000, -1000, 2140, -189, -1000, -1000, -1000, 284, - -494, -291, -292, 25086, -1000, 22860, -1000, 22860, -1000, 22860, - -1000, 54766, 1830, -1000, -1000, -1000, 1426, -1000, 4978, -334, - 2177, -1000, -126, -1000, -1000, -1000, 1042, 1359, -1000, -1000, - -1000, -1000, -1000, -1000, 1936, 54766, -1000, 446, -1000, -1000, - 16164, -186, -201, 1000, -1000, -1000, -1000, -1000, -1000, 2007, - 1365, 1353, 1538, -1000, 54766, -1000, 54024, -314, 899, 6271, - -1000, 2164, 2159, 2656, -1000, -1000, -1000, -1000, -1000, -1000, - -544, 1356, 243, -1000, -1000, -1000, 284, -338, -1000, 22860, - -1000, 22860, -1000, 1406, -1000, -1000, 2494, 75, -1000, 2658, - -1000, 2643, 1016, 1016, -1000, 1136, -544, -1000, -1000, -1000, - -1000, 1538, 1538, -1000, -354, -1000, -1000, -1000, -1000, -1000, - 440, 1275, -1000, -1000, -1000, -1000, -1000, 6271, -1000, -1000, - -1000, 263, 263, -1000, -1000, + 22251, -1000, 1378, 2167, -1000, -375, -1000, -514, 22251, -279, + -1000, -1000, -279, -1000, -1000, -1000, -1000, -1000, 22251, -1000, + -1000, 22251, -1000, 22251, -1000, -1000, 1671, -1000, -1000, -1000, + 37171, -1000, 1671, -1000, 1671, -1000, -288, -1000, 1900, -1000, + 54329, 1527, 391, -1000, 1191, -1000, -1000, -1000, -1000, -1000, + 55075, 54329, 1925, 54329, -1000, -1000, 1628, 1378, 1998, 2565, + -1000, 1604, -1000, 400, -1000, 2012, 2116, -1000, -1000, -1000, + 20013, -1000, -1000, -1000, -1000, -1000, 272, -197, 16271, 11759, + 1602, -1000, -195, 1681, 1554, -1000, -481, -1000, -1000, -1000, + -1000, 263, -1000, -1000, 1892, -1000, -1000, 1714, 1710, 1677, + -1000, -1000, -1000, -1000, -1000, -1000, -288, -1000, -1000, 2511, + -1000, -253, -1000, -1000, 1890, 1547, -1000, -1000, -1000, 31949, + 53583, -1000, -179, 325, -197, 22251, 2011, 1378, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -40, -1000, -1000, 540, + -1000, -1000, -1000, 2131, -212, -1000, -1000, -1000, 292, -497, + -259, -293, 24489, -1000, 22251, -1000, 22251, -1000, 22251, -1000, + 54329, 1998, -1000, -1000, -1000, 1484, -1000, 4304, -394, 2163, + -1000, -143, -1000, -1000, -1000, 1049, 1373, -1000, -1000, -1000, + -1000, -1000, -1000, 1850, 54329, -1000, 435, -1000, -1000, 15519, + -203, -228, 1010, -1000, -1000, -1000, -1000, -1000, 1029, 1616, + 1377, 1681, -1000, 54329, -1000, 53583, -387, 901, 5242, -1000, + 2159, 2155, 2657, -1000, -1000, -1000, -1000, -1000, -1000, -548, + 1482, 242, -1000, -1000, -1000, 292, -328, -1000, 22251, -1000, + 22251, -1000, 1378, -1000, -1000, 2496, 55, -1000, 2672, -1000, + 2675, 1014, 1014, -1000, 1126, -548, -1000, -1000, -1000, -1000, + 1681, 1681, -1000, -396, -1000, -1000, -1000, -1000, -1000, 430, + 1220, -1000, -1000, -1000, -1000, -1000, 5242, -1000, -1000, -1000, + 235, 235, -1000, -1000, } var yyPgo = [...]int{ - 0, 3243, 3242, 31, 6, 37, 36, 3240, 3239, 3238, - 174, 3237, 3235, 3224, 3223, 3222, 3221, 2754, 2745, 2728, - 3220, 3219, 3218, 3215, 3213, 3211, 3210, 3209, 3208, 38, - 116, 91, 104, 201, 213, 3205, 170, 161, 197, 3203, - 3202, 3201, 115, 187, 84, 92, 195, 3200, 3199, 71, - 3196, 3194, 3192, 190, 189, 188, 1092, 3190, 184, 114, - 48, 3189, 3187, 3184, 3182, 3179, 3178, 3176, 3174, 3173, - 3172, 3170, 3169, 3168, 3165, 3163, 3162, 3161, 3160, 285, - 3157, 3155, 12, 3154, 73, 3153, 3152, 3149, 3147, 3146, - 8, 3140, 3139, 26, 45, 63, 3136, 3134, 44, 3132, - 3131, 3129, 3125, 3124, 72, 3123, 27, 3121, 40, 3120, - 3117, 124, 3115, 3111, 3105, 42, 3104, 3100, 3098, 28, - 169, 3097, 3094, 140, 3093, 3092, 3087, 167, 205, 3085, - 2265, 3082, 99, 3080, 3079, 3077, 166, 193, 3076, 125, - 3074, 3073, 3072, 152, 3068, 3263, 3066, 3065, 59, 80, - 164, 3064, 3062, 199, 79, 54, 3061, 17, 19, 3060, - 3058, 67, 70, 3057, 108, 3056, 3054, 103, 77, 3052, - 105, 102, 3051, 3050, 5, 7, 3048, 1, 4, 2, - 83, 3047, 3044, 119, 3041, 3040, 3039, 101, 3037, 3035, - 4407, 3031, 93, 130, 106, 76, 3028, 171, 132, 3027, - 3026, 3022, 3021, 3016, 2985, 49, 2984, 2983, 2982, 136, - 22, 110, 2981, 146, 346, 51, 147, 2978, 196, 78, - 2977, 172, 2971, 2969, 134, 133, 2968, 2962, 58, 168, - 194, 2960, 96, 129, 120, 176, 95, 135, 2954, 2946, - 56, 62, 2944, 2943, 2940, 2939, 181, 2935, 2929, 61, - 2927, 53, 2925, 182, 2924, 306, 69, 2922, 180, 162, - 2921, 60, 2919, 2918, 68, 100, 55, 39, 2914, 157, - 160, 127, 165, 2913, 2912, 52, 2905, 2899, 2894, 200, - 301, 2891, 2890, 329, 183, 143, 149, 85, 2887, 323, - 2886, 2885, 2884, 16, 5094, 7550, 186, 25, 159, 2883, - 2882, 8334, 20, 43, 24, 2872, 210, 2869, 185, 2867, - 2866, 2865, 211, 207, 112, 158, 57, 2864, 2859, 2857, - 2856, 64, 2855, 2850, 2849, 2848, 2847, 2846, 35, 34, - 33, 75, 218, 65, 21, 98, 156, 151, 66, 2843, - 2841, 2839, 123, 90, 2835, 155, 153, 126, 163, 2829, - 175, 142, 117, 2823, 87, 32, 2822, 2821, 2819, 2818, - 89, 2813, 2810, 2806, 2805, 150, 144, 121, 81, 2803, - 82, 118, 148, 145, 50, 2799, 46, 2798, 2797, 30, - 191, 29, 2787, 13, 111, 109, 2780, 6691, 2779, 9, - 305, 154, 2776, 2775, 10, 11, 14, 2772, 2771, 2770, - 2769, 131, 2768, 2765, 2763, 2761, 23, 47, 18, 15, - 113, 137, 74, 2760, 2746, 141, 2732, 2727, 2722, 0, - 1034, 128, 2721, 202, + 0, 3261, 3259, 47, 7, 36, 34, 3256, 3254, 3239, + 178, 3238, 3237, 3236, 3235, 3234, 3233, 2715, 2702, 2700, + 3229, 3228, 3226, 3225, 3224, 3222, 3220, 3218, 3217, 48, + 110, 72, 108, 213, 215, 3216, 3215, 184, 173, 202, + 3209, 3208, 3207, 116, 193, 83, 87, 197, 3202, 3195, + 78, 3191, 3189, 3188, 191, 190, 189, 1088, 3187, 188, + 114, 50, 3186, 3185, 3182, 3178, 3176, 3175, 3174, 3172, + 3170, 3168, 3167, 3165, 3162, 3156, 3155, 3153, 3150, 3146, + 309, 3143, 3142, 10, 3141, 66, 3139, 3135, 3133, 3130, + 3126, 12, 3125, 3123, 19, 42, 60, 3122, 3119, 49, + 3118, 3114, 3112, 3109, 3107, 45, 3105, 27, 3104, 37, + 3103, 3102, 128, 3100, 3099, 3098, 38, 3097, 3095, 3094, + 5, 170, 3093, 3091, 142, 3090, 3082, 3081, 169, 222, + 3078, 2332, 3074, 99, 3071, 3068, 3061, 174, 200, 3058, + 122, 3057, 3055, 3053, 155, 3044, 3333, 3041, 3039, 68, + 76, 156, 3036, 3034, 199, 74, 11, 3031, 15, 17, + 3030, 3025, 69, 64, 3021, 111, 3013, 3010, 103, 65, + 3009, 100, 97, 3008, 3006, 23, 18, 3003, 6, 1, + 8, 82, 3002, 3001, 119, 2997, 2983, 2982, 93, 2981, + 2979, 3360, 2977, 90, 136, 106, 70, 2968, 171, 153, + 2967, 2966, 2965, 2964, 2963, 2960, 53, 2958, 2957, 2954, + 140, 29, 113, 2953, 2950, 146, 346, 130, 54, 132, + 2947, 149, 2945, 203, 77, 2943, 175, 2941, 2940, 135, + 134, 2938, 2937, 57, 168, 194, 2928, 96, 131, 121, + 150, 94, 133, 2926, 2925, 58, 61, 2911, 2909, 2907, + 2904, 177, 2902, 2901, 62, 2900, 56, 2899, 167, 2897, + 302, 67, 2896, 180, 185, 2895, 73, 2891, 2889, 91, + 95, 102, 26, 2888, 163, 166, 127, 182, 2887, 2884, + 55, 2881, 2879, 2878, 201, 280, 2877, 2873, 308, 179, + 144, 152, 84, 2871, 325, 2869, 2864, 2863, 40, 4520, + 6444, 192, 22, 165, 2860, 2856, 7650, 44, 39, 24, + 2855, 210, 2854, 183, 2853, 2846, 2841, 238, 207, 112, + 164, 59, 2839, 2838, 2836, 2835, 35, 2830, 2828, 2818, + 2816, 2814, 2813, 33, 32, 31, 92, 216, 81, 20, + 98, 172, 157, 63, 2812, 2811, 2810, 125, 85, 2809, + 162, 159, 126, 101, 2807, 186, 145, 118, 2804, 105, + 30, 2799, 2798, 2797, 2796, 89, 2795, 2794, 2791, 2786, + 154, 147, 123, 79, 2784, 80, 120, 151, 148, 52, + 2782, 43, 2781, 2780, 28, 195, 25, 2776, 41, 107, + 117, 2775, 6234, 2774, 9, 335, 161, 2771, 2765, 4, + 13, 16, 2764, 2759, 2748, 2741, 138, 2740, 2739, 2738, + 2732, 21, 46, 14, 2, 115, 141, 71, 2730, 2727, + 143, 2726, 2724, 2708, 0, 1034, 129, 2701, 204, } -//line sql.y:8764 +//line sql.y:8811 type yySymType struct { union any empty struct{} @@ -8490,6 +8457,11 @@ func (st *yySymType) tableSpecUnion() *TableSpec { return v } +func (st *yySymType) tableStmtUnion() TableStatement { + v, _ := st.union.(TableStatement) + return v +} + func (st *yySymType) trimTypeUnion() TrimType { v, _ := st.union.(TrimType) return v @@ -8576,235 +8548,237 @@ func (st *yySymType) withUnion() *With { } var yyR1 = [...]int{ - 0, 417, 418, 418, 7, 7, 7, 7, 7, 7, + 0, 422, 423, 423, 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, 261, 387, 259, 259, 28, 74, 36, 36, 35, - 35, 38, 38, 37, 31, 31, 31, 32, 32, 32, + 7, 266, 392, 264, 264, 28, 75, 37, 37, 36, + 36, 39, 39, 38, 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, 421, 421, 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, 315, 315, 315, 22, 22, 22, 22, - 22, 129, 129, 389, 389, 388, 383, 383, 382, 382, - 381, 386, 386, 385, 385, 384, 40, 41, 50, 50, - 50, 50, 51, 52, 390, 390, 356, 57, 57, 56, - 56, 56, 56, 56, 56, 58, 58, 54, 54, 53, - 53, 55, 55, 358, 358, 344, 344, 357, 357, 357, - 357, 357, 357, 357, 343, 343, 140, 140, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 405, 405, 405, 404, 404, - 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, 409, 409, - 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, - 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, - 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, - 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, - 160, 160, 155, 155, 155, 157, 157, 156, 156, 156, - 158, 158, 406, 406, 406, 406, 321, 321, 321, 321, - 324, 324, 322, 322, 322, 322, 322, 322, 322, 322, - 322, 323, 323, 323, 323, 323, 323, 323, 325, 325, - 325, 325, 325, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 327, 327, 327, 327, 327, 327, 327, 327, 342, 342, - 331, 331, 336, 336, 337, 337, 338, 338, 338, 339, - 339, 339, 340, 340, 333, 333, 333, 333, 333, 333, - 333, 333, 333, 335, 335, 334, 334, 334, 345, 370, - 370, 369, 369, 367, 367, 367, 367, 367, 367, 367, - 367, 354, 354, 364, 364, 364, 364, 364, 353, 353, - 349, 349, 349, 350, 350, 351, 351, 348, 348, 352, - 352, 366, 366, 365, 365, 346, 346, 347, 347, 372, - 407, 407, 407, 407, 407, 408, 408, 373, 397, 399, - 399, 399, 398, 398, 395, 396, 394, 394, 394, 394, - 394, 84, 84, 84, 287, 287, 288, 288, 362, 362, - 361, 361, 361, 363, 363, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 282, 282, 282, 393, - 393, 393, 393, 393, 393, 392, 392, 392, 359, 359, - 359, 359, 391, 391, 59, 59, 219, 219, 410, 410, - 412, 412, 412, 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, - 42, 42, 42, 48, 48, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 23, 23, 23, 23, 23, + 29, 29, 29, 29, 30, 30, 30, 30, 30, 35, + 35, 15, 16, 34, 34, 34, 17, 17, 110, 110, + 18, 19, 19, 19, 19, 426, 426, 186, 186, 184, + 184, 185, 185, 269, 269, 20, 273, 273, 275, 275, + 275, 275, 265, 265, 265, 21, 21, 274, 274, 276, + 276, 276, 279, 279, 279, 279, 320, 320, 320, 22, + 22, 22, 22, 22, 130, 130, 394, 394, 393, 388, + 388, 387, 387, 386, 391, 391, 390, 390, 389, 41, + 42, 51, 51, 51, 51, 52, 53, 395, 395, 361, + 58, 58, 57, 57, 57, 57, 57, 57, 59, 59, + 55, 55, 54, 54, 56, 56, 363, 363, 349, 349, + 362, 362, 362, 362, 362, 362, 362, 348, 348, 141, + 141, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 410, 410, + 410, 409, 409, 244, 244, 244, 244, 244, 244, 244, + 244, 150, 150, 162, 162, 162, 162, 162, 162, 148, + 148, 149, 147, 147, 147, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 414, 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 161, 161, 156, 156, 156, 158, 158, + 157, 157, 157, 159, 159, 411, 411, 411, 411, 326, + 326, 326, 326, 329, 329, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 328, 328, 328, 328, 328, 328, + 328, 330, 330, 330, 330, 330, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 332, 332, 332, 332, 332, 332, 332, + 332, 347, 347, 336, 336, 341, 341, 342, 342, 343, + 343, 343, 344, 344, 344, 345, 345, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 340, 340, 339, 339, + 339, 350, 375, 375, 374, 374, 372, 372, 372, 372, + 372, 372, 372, 372, 359, 359, 369, 369, 369, 369, + 369, 358, 358, 354, 354, 354, 355, 355, 356, 356, + 353, 353, 357, 357, 371, 371, 370, 370, 351, 351, + 352, 352, 377, 412, 412, 412, 412, 412, 413, 413, + 378, 402, 404, 404, 404, 403, 403, 400, 401, 399, + 399, 399, 399, 399, 85, 85, 85, 292, 292, 293, + 293, 367, 367, 366, 366, 366, 368, 368, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 287, + 287, 287, 398, 398, 398, 398, 398, 398, 397, 397, + 397, 364, 364, 364, 364, 396, 396, 60, 60, 224, + 224, 415, 415, 417, 417, 417, 48, 48, 48, 48, + 48, 48, 47, 47, 47, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 49, 49, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 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, 23, 23, 23, 23, 111, - 111, 112, 112, 112, 112, 114, 114, 114, 375, 375, - 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, 380, - 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, - 380, 341, 341, 341, 374, 374, 376, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 117, 116, 116, - 115, 118, 118, 118, 118, 118, 118, 118, 118, 378, - 378, 378, 63, 63, 379, 328, 329, 330, 5, 6, - 355, 377, 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, 65, - 65, 65, 292, 292, 281, 281, 290, 290, 280, 280, - 306, 306, 306, 283, 283, 283, 284, 284, 403, 403, - 403, 277, 277, 66, 66, 66, 307, 307, 307, 307, - 69, 69, 413, 413, 414, 414, 415, 415, 415, 70, - 71, 71, 310, 310, 311, 311, 72, 73, 85, 85, - 85, 85, 85, 86, 86, 86, 86, 86, 86, 110, - 110, 110, 10, 10, 10, 10, 81, 81, 81, 9, - 9, 11, 68, 68, 75, 400, 400, 401, 402, 402, - 402, 402, 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, 422, - 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, - 136, 136, 136, 136, 131, 131, 132, 132, 132, 132, - 299, 299, 299, 298, 298, 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, 309, 309, 304, 304, 304, 303, - 303, 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, - 411, 411, 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, 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, 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, 296, - 296, 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, 205, - 205, 164, 164, 164, 164, 227, 227, 151, 151, 151, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 112, 112, 113, 113, 113, 113, 115, 115, + 115, 380, 380, 61, 61, 3, 3, 174, 176, 177, + 177, 175, 175, 175, 175, 175, 175, 63, 63, 62, + 62, 179, 178, 180, 180, 180, 1, 1, 2, 2, + 4, 4, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 346, 346, 346, 379, 379, 381, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 118, 117, 117, 116, 119, 119, 119, 119, 119, 119, + 119, 119, 383, 383, 383, 64, 64, 384, 333, 334, + 335, 5, 6, 360, 382, 126, 126, 24, 40, 40, + 25, 25, 25, 25, 26, 26, 65, 68, 68, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 297, 297, 286, 286, 295, + 295, 285, 285, 311, 311, 311, 288, 288, 288, 289, + 289, 408, 408, 408, 282, 282, 67, 67, 67, 312, + 312, 312, 312, 70, 70, 418, 418, 419, 419, 420, + 420, 420, 71, 72, 72, 315, 315, 316, 316, 73, + 74, 86, 86, 86, 86, 86, 87, 87, 87, 87, + 87, 87, 111, 111, 111, 10, 10, 10, 10, 82, + 82, 82, 9, 9, 11, 69, 69, 76, 405, 405, + 406, 407, 407, 407, 407, 77, 79, 27, 27, 27, + 27, 27, 27, 136, 136, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 131, 131, 131, + 125, 125, 427, 80, 81, 81, 129, 129, 129, 122, + 122, 122, 128, 128, 128, 12, 12, 13, 268, 268, + 14, 14, 135, 135, 134, 134, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 132, 132, 133, + 133, 133, 133, 304, 304, 304, 303, 303, 168, 168, + 170, 169, 169, 171, 171, 172, 172, 172, 172, 222, + 222, 194, 194, 261, 261, 262, 262, 260, 260, 267, + 267, 263, 263, 263, 263, 270, 270, 173, 173, 173, + 173, 181, 181, 182, 182, 183, 183, 314, 314, 309, + 309, 309, 308, 308, 187, 187, 187, 189, 188, 188, + 188, 188, 190, 190, 192, 192, 191, 191, 193, 198, + 198, 197, 197, 195, 195, 195, 195, 195, 195, 196, + 196, 196, 196, 199, 199, 146, 146, 146, 146, 146, + 146, 146, 146, 416, 416, 160, 160, 160, 160, 160, + 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 251, 251, 151, 151, 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, 317, 317, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 120, 120, 120, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 227, 227, 226, 226, 88, + 88, 88, 89, 89, 90, 90, 90, 90, 90, 91, + 91, 91, 91, 91, 91, 91, 93, 93, 92, 92, + 213, 213, 301, 301, 94, 95, 95, 96, 96, 99, + 99, 98, 97, 97, 103, 103, 100, 100, 102, 102, + 101, 104, 104, 105, 106, 106, 283, 283, 200, 200, + 209, 209, 209, 209, 201, 201, 202, 202, 202, 202, + 202, 202, 210, 210, 210, 221, 211, 211, 207, 207, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 165, 165, 165, 165, 232, 232, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 153, 153, 166, 166, 166, + 166, 167, 167, 167, 167, 167, 167, 167, 322, 322, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 423, 423, 332, 332, 332, - 207, 207, 207, 207, 207, 126, 126, 126, 126, 126, - 314, 314, 314, 318, 318, 318, 316, 316, 316, 316, - 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, - 316, 319, 319, 225, 225, 122, 122, 223, 223, 224, - 226, 226, 218, 218, 218, 218, 220, 220, 203, 203, - 203, 228, 228, 320, 320, 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, 308, 308, 308, - 266, 266, 213, 213, 215, 215, 214, 214, 163, 267, - 267, 275, 272, 272, 273, 273, 300, 300, 300, 276, - 276, 289, 289, 285, 285, 286, 286, 279, 279, 291, - 291, 291, 77, 211, 211, 371, 371, 368, 295, 295, - 297, 297, 301, 301, 305, 305, 302, 302, 8, 416, - 416, 416, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 419, 420, 312, 313, 313, 313, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 428, 428, + 337, 337, 337, 208, 208, 208, 208, 208, 127, 127, + 127, 127, 127, 319, 319, 319, 323, 323, 323, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 321, 321, 324, 324, 230, 230, 123, 123, + 228, 228, 229, 231, 231, 223, 223, 223, 223, 225, + 225, 204, 204, 204, 233, 233, 325, 325, 234, 234, + 107, 108, 108, 109, 109, 235, 235, 237, 236, 236, + 238, 239, 239, 239, 240, 240, 241, 241, 241, 50, + 50, 50, 50, 50, 45, 45, 45, 45, 46, 46, + 46, 46, 138, 138, 138, 138, 140, 140, 139, 139, + 83, 83, 84, 84, 84, 144, 144, 145, 145, 145, + 142, 142, 143, 143, 258, 258, 258, 258, 258, 258, + 258, 242, 242, 242, 249, 249, 249, 245, 245, 247, + 247, 247, 248, 248, 248, 246, 255, 255, 257, 257, + 256, 256, 252, 252, 253, 253, 254, 254, 254, 250, + 250, 203, 203, 203, 203, 203, 259, 259, 259, 259, + 313, 313, 313, 271, 271, 214, 214, 215, 215, 219, + 219, 218, 218, 216, 217, 220, 220, 164, 272, 272, + 280, 277, 277, 278, 278, 305, 305, 305, 281, 281, + 294, 294, 290, 290, 291, 291, 284, 284, 296, 296, + 296, 78, 212, 212, 376, 376, 373, 300, 300, 302, + 302, 306, 306, 310, 310, 307, 307, 8, 421, 421, + 421, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, 298, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 424, 425, 317, 318, + 318, 318, } var yyR2 = [...]int{ @@ -8815,164 +8789,165 @@ var yyR2 = [...]int{ 0, 1, 1, 1, 1, 2, 3, 2, 3, 0, 1, 3, 1, 4, 3, 3, 4, 3, 2, 3, 4, 3, 4, 2, 7, 1, 3, 3, 3, 3, - 1, 2, 1, 1, 3, 2, 3, 3, 2, 5, - 7, 10, 9, 7, 8, 1, 1, 10, 11, 9, - 8, 8, 1, 1, 1, 3, 1, 3, 1, 3, - 0, 4, 3, 1, 3, 3, 3, 3, 3, 1, - 1, 2, 5, 4, 1, 3, 3, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 2, 2, 6, 12, - 2, 0, 2, 0, 2, 1, 0, 2, 1, 3, - 3, 0, 1, 1, 3, 3, 6, 4, 7, 8, - 8, 8, 5, 3, 1, 1, 5, 0, 1, 1, - 1, 1, 2, 2, 2, 0, 1, 4, 4, 4, - 4, 4, 4, 2, 4, 1, 3, 1, 1, 3, - 4, 3, 3, 3, 5, 10, 0, 2, 0, 2, - 3, 5, 3, 4, 2, 3, 2, 3, 3, 3, - 3, 2, 2, 4, 4, 1, 1, 1, 1, 1, - 0, 2, 2, 3, 3, 2, 2, 2, 1, 1, - 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, - 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 3, 2, 3, 3, 2, 3, + 3, 5, 7, 10, 9, 1, 7, 8, 1, 1, + 10, 11, 9, 8, 8, 1, 1, 1, 3, 1, + 3, 1, 3, 0, 4, 3, 1, 3, 3, 3, + 3, 3, 1, 1, 2, 5, 4, 1, 3, 3, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, + 2, 6, 12, 2, 0, 2, 0, 2, 1, 0, + 2, 1, 3, 3, 0, 1, 1, 3, 3, 6, + 4, 7, 8, 8, 8, 5, 3, 1, 1, 5, + 0, 1, 1, 1, 1, 2, 2, 2, 0, 1, + 4, 4, 4, 4, 4, 4, 2, 4, 1, 3, + 1, 1, 3, 4, 3, 3, 3, 5, 10, 0, + 2, 0, 2, 3, 5, 3, 4, 2, 3, 2, + 3, 3, 3, 3, 2, 2, 4, 4, 1, 1, + 1, 1, 1, 0, 2, 2, 3, 3, 2, 2, + 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 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, 1, 2, 1, 1, 2, - 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 1, 5, 2, 5, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 0, 3, 0, 5, 1, 3, 0, 3, 5, 0, - 1, 1, 0, 1, 0, 3, 3, 2, 2, 2, - 1, 2, 2, 0, 1, 0, 2, 2, 5, 0, - 1, 1, 2, 1, 3, 2, 1, 1, 3, 3, - 3, 0, 1, 4, 3, 3, 4, 2, 0, 2, - 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, - 1, 1, 3, 3, 4, 3, 1, 3, 1, 7, - 6, 7, 7, 8, 8, 0, 1, 5, 2, 1, - 1, 1, 0, 1, 3, 3, 1, 1, 2, 2, - 2, 0, 1, 1, 1, 2, 0, 1, 0, 1, - 1, 3, 2, 1, 2, 3, 3, 3, 4, 4, - 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 2, 1, 1, 2, 1, 2, 1, 3, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 5, 2, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 0, 3, 0, 5, 1, 3, 0, + 3, 5, 0, 1, 1, 0, 1, 0, 3, 3, + 2, 2, 2, 1, 2, 2, 0, 1, 0, 2, + 2, 5, 0, 1, 1, 2, 1, 3, 2, 1, + 1, 3, 3, 3, 0, 1, 4, 3, 3, 4, + 2, 0, 2, 1, 1, 1, 1, 1, 0, 1, + 1, 1, 0, 1, 1, 3, 3, 4, 3, 1, + 3, 1, 7, 6, 7, 7, 8, 8, 0, 1, + 5, 2, 1, 1, 1, 0, 1, 3, 3, 1, + 1, 2, 2, 2, 0, 1, 1, 1, 2, 0, + 1, 0, 1, 1, 3, 2, 1, 2, 3, 3, + 3, 4, 4, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 5, 0, 2, 2, 1, + 3, 3, 3, 3, 3, 3, 3, 4, 5, 0, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 1, 0, 1, 0, 1, 0, + 2, 0, 2, 0, 2, 2, 0, 1, 5, 1, + 3, 7, 1, 3, 3, 1, 2, 2, 2, 5, + 5, 5, 6, 8, 5, 5, 4, 4, 4, 6, + 5, 5, 5, 2, 2, 2, 2, 3, 3, 3, + 4, 3, 3, 1, 3, 5, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 2, 3, 4, + 4, 2, 11, 3, 6, 8, 6, 6, 6, 13, + 8, 6, 6, 10, 7, 5, 5, 5, 5, 7, + 5, 5, 5, 5, 5, 7, 7, 5, 5, 5, + 5, 6, 0, 6, 5, 6, 4, 5, 0, 8, + 9, 0, 3, 0, 1, 0, 3, 8, 4, 1, + 3, 3, 6, 7, 7, 8, 4, 0, 1, 0, + 1, 3, 3, 1, 1, 2, 1, 1, 0, 2, + 0, 2, 5, 3, 7, 4, 4, 4, 4, 3, + 3, 3, 7, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 0, 2, 2, 1, 3, 2, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 1, 3, 3, 0, 2, 2, 2, 2, 2, + 2, 2, 4, 4, 3, 0, 1, 4, 3, 4, + 4, 3, 3, 3, 2, 1, 3, 3, 3, 5, + 7, 7, 6, 5, 3, 2, 4, 5, 5, 3, + 3, 7, 3, 3, 3, 3, 4, 7, 5, 2, + 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, + 4, 4, 2, 3, 3, 3, 3, 3, 5, 2, + 3, 3, 2, 3, 4, 4, 4, 3, 4, 4, + 5, 3, 5, 3, 5, 0, 1, 0, 1, 0, + 1, 1, 1, 0, 2, 2, 0, 2, 2, 0, + 2, 0, 1, 1, 1, 1, 2, 1, 3, 1, + 1, 1, 1, 1, 3, 0, 1, 1, 3, 3, + 2, 2, 1, 1, 5, 0, 1, 0, 1, 2, + 3, 0, 3, 3, 3, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 4, 4, 4, 2, 2, 3, 1, 3, + 2, 1, 2, 1, 2, 2, 4, 3, 3, 6, + 4, 7, 6, 1, 3, 2, 2, 2, 2, 1, + 1, 1, 3, 2, 1, 1, 1, 0, 1, 1, + 0, 3, 0, 2, 0, 2, 1, 2, 2, 0, + 1, 1, 0, 1, 1, 5, 5, 4, 0, 2, + 4, 4, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 0, 1, 0, 1, 0, 2, 0, 2, - 0, 2, 2, 0, 1, 5, 1, 3, 7, 1, - 3, 3, 1, 2, 2, 2, 5, 5, 5, 6, - 8, 5, 5, 4, 4, 4, 6, 5, 5, 5, - 2, 2, 2, 2, 3, 3, 3, 4, 3, 3, - 1, 3, 5, 1, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 3, 4, 4, 2, 11, - 3, 6, 8, 6, 6, 6, 13, 8, 6, 6, - 10, 7, 5, 5, 5, 5, 7, 5, 5, 5, - 5, 5, 7, 7, 5, 5, 5, 5, 6, 0, - 6, 5, 6, 4, 5, 0, 8, 9, 0, 3, - 0, 1, 0, 3, 8, 4, 1, 3, 3, 6, - 7, 7, 8, 4, 0, 1, 0, 1, 3, 3, - 1, 1, 2, 1, 1, 0, 2, 0, 2, 5, - 3, 7, 4, 4, 4, 4, 3, 3, 3, 7, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 0, 2, 2, 1, 3, 2, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 3, 1, 3, - 3, 0, 2, 2, 2, 2, 2, 2, 2, 4, - 4, 3, 0, 1, 4, 3, 4, 4, 3, 3, - 3, 2, 1, 3, 3, 3, 5, 7, 7, 6, - 5, 3, 2, 4, 5, 5, 3, 3, 7, 3, - 3, 3, 3, 4, 7, 5, 2, 4, 4, 4, - 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, - 4, 4, 2, 2, 4, 4, 4, 4, 4, 2, - 3, 3, 3, 3, 3, 5, 2, 3, 3, 2, - 3, 4, 4, 4, 3, 4, 4, 5, 3, 5, - 3, 5, 0, 1, 0, 1, 0, 1, 1, 1, - 0, 2, 2, 0, 2, 2, 0, 2, 0, 1, - 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, - 1, 3, 0, 1, 1, 3, 3, 2, 2, 1, - 1, 5, 0, 1, 0, 1, 2, 3, 0, 3, - 3, 3, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, - 4, 4, 2, 2, 3, 1, 3, 2, 1, 2, - 1, 2, 2, 4, 3, 3, 6, 4, 7, 6, - 1, 3, 2, 2, 2, 2, 1, 1, 1, 3, - 2, 1, 1, 1, 0, 1, 1, 0, 3, 0, - 2, 0, 2, 1, 2, 2, 0, 1, 1, 0, - 1, 1, 5, 5, 4, 0, 2, 4, 4, 0, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 1, 2, 3, 5, - 0, 1, 2, 1, 1, 0, 1, 2, 1, 3, - 1, 1, 1, 4, 3, 1, 1, 2, 3, 7, - 0, 3, 0, 1, 1, 3, 1, 3, 1, 1, - 3, 3, 1, 3, 4, 4, 4, 3, 2, 4, - 0, 1, 0, 2, 0, 1, 0, 1, 2, 1, - 1, 1, 2, 2, 1, 2, 3, 2, 3, 2, - 2, 2, 1, 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, 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, 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, - 5, 7, 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, + 2, 3, 5, 0, 1, 2, 1, 1, 0, 1, + 2, 1, 3, 1, 1, 1, 4, 3, 1, 1, + 2, 3, 7, 0, 3, 0, 1, 1, 3, 1, + 3, 1, 1, 3, 3, 1, 3, 4, 4, 4, + 3, 2, 4, 0, 1, 0, 2, 0, 1, 0, + 1, 2, 1, 1, 1, 2, 2, 1, 2, 3, + 2, 3, 2, 2, 2, 1, 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, 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, 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, 5, 7, 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, 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, + 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, 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, 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, 3, 1, + 3, 1, 2, 3, 4, 1, 1, 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, @@ -9036,568 +9011,571 @@ 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, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, } var yyChk = [...]int{ - -1000, -417, -79, -422, -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, 13, 14, -109, -35, 35, -40, - -50, 240, -51, -41, 241, -52, 243, 242, 280, 244, - 397, 273, 83, 330, 331, 333, 334, 335, 336, -110, - 704, 278, 279, 246, 39, 51, 36, 37, 40, 250, - 286, 287, 249, 145, -33, -36, 12, -419, 15, 487, - 275, 274, 31, -34, 597, 95, -80, -418, 752, -253, - -237, 26, 36, 32, -236, -232, -128, -237, 24, 22, - 11, -79, -79, -79, 16, 17, -79, -356, -358, 95, - 173, 95, -79, -57, -56, -54, -53, -55, -58, 34, - -47, -48, -380, -46, -43, 245, 242, 290, 135, 136, - 280, 281, 282, 244, 264, 279, 283, 278, 299, -42, - 90, 36, 597, 600, -363, 241, 247, 248, 243, 488, - 138, 137, 84, -360, 392, 631, 722, -58, 724, 110, - 113, 723, 50, 254, 725, 726, 727, 638, 728, 263, - 729, 730, 731, 732, 738, 679, 739, 740, 741, 139, - 11, -79, -305, -301, 100, -294, 594, 266, 629, 441, - 630, 315, 90, 47, 42, 533, 604, 388, 392, 631, - 518, 722, 398, 330, 348, 342, 523, 524, 525, 371, - 363, 595, 632, 605, 318, 267, 303, 716, 361, 149, - 724, 322, 633, 281, 399, 400, 634, 401, 110, 333, - 438, 737, 321, 635, 735, 113, 723, 338, 88, 517, - 57, 719, 326, 50, 276, 446, 447, 359, 249, 355, - 725, 304, 636, 607, 297, 138, 135, 744, 39, 351, - 56, 33, 734, 137, 55, 726, 164, 637, 727, 638, - 403, 378, 710, 54, 404, 282, 639, 93, 287, 599, - 327, 718, 405, 538, 352, 406, 314, 733, 246, 640, - 325, 699, 691, 692, 407, 408, 711, 383, 379, 384, - 540, 641, 430, 522, 409, 695, 696, 751, 58, 642, - 643, 712, 136, 644, 87, 728, 89, 346, 347, 645, - 312, 265, 543, 544, 432, 375, 500, 127, 507, 508, - 120, 121, 503, 122, 509, 123, 128, 510, 511, 512, - 501, 124, 117, 502, 513, 514, 376, 377, 125, 515, - 119, 118, 504, 506, 126, 516, 263, 38, 410, 596, - 316, 64, 320, 291, 433, 52, 381, 748, 51, 706, - 545, 646, 709, 374, 370, 497, 59, 647, 648, 649, - 650, 519, 729, 373, 345, 369, 743, 4, 309, 492, - 520, 730, 68, 248, 386, 385, 387, 298, 429, 366, - 651, 652, 653, 270, 91, 654, 356, 25, 655, 656, - 411, 305, 657, 62, 658, 659, 436, 279, 660, 60, - 731, 45, 661, 284, 745, 732, 662, 663, 664, 705, - 665, 286, 666, 413, 667, 693, 694, 412, 380, 382, - 546, 293, 414, 397, 251, 598, 668, 328, 350, 283, - 736, 669, 271, 534, 535, 536, 537, 717, 542, 541, - 285, 290, 278, 437, 272, 670, 671, 672, 673, 674, - 319, 690, 675, 676, 334, 602, 738, 498, 49, 677, - 678, 679, 680, 681, 313, 308, 431, 440, 67, 92, - 394, 682, 683, 715, 344, 339, 43, 306, 99, 478, - 480, 481, 482, 483, 484, 479, 486, 684, 331, 61, - 739, 740, 741, 300, 742, 526, 527, 528, 529, 13, - 580, 563, 591, 564, 581, 565, 574, 566, 582, 590, - 592, 547, 555, 548, 556, 586, 569, 583, 575, 568, - 567, 589, 572, 576, 549, 557, 587, 573, 550, 558, - 551, 559, 552, 560, 585, 584, 577, 588, 553, 561, - 579, 554, 562, 578, 570, 571, 449, 749, 750, 521, - 416, 139, 310, 311, 53, 367, 292, 685, 323, 686, - 357, 358, 494, 495, 372, 343, 368, 146, 702, 332, - 341, 700, 294, 417, 499, 280, 687, 439, 307, 389, - 131, 340, 395, 324, 603, 539, 299, 418, 714, 601, - 530, 531, 365, 362, 301, 532, 688, 390, 704, 419, - 255, 295, 296, 689, 701, 420, 421, 317, 422, 423, - 424, 425, 426, 428, 329, 427, 703, 697, 698, 302, - 477, 600, 337, 360, 396, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 496, 253, -79, 253, -190, -301, -130, - 706, 708, 192, -272, 400, -290, 402, 415, 410, 420, - 408, -281, 411, 413, 293, -403, 430, 253, 417, 240, - 403, 412, 421, 422, 317, 428, 423, 329, 427, 302, - 424, 425, 426, -387, 192, 727, 742, 332, 340, 149, - 364, 407, 405, 431, 706, 100, -307, 100, 101, 102, - -294, 332, -310, 337, -295, -387, -294, 335, -79, -79, - -312, -312, -130, -210, -145, 157, -159, -261, -162, 101, - -150, -153, -204, -205, -206, -207, -160, -220, -259, 181, - 182, 189, 158, -216, -163, 29, 593, 489, 488, 192, - 34, 235, 77, 78, 491, 492, 160, 63, 15, 454, - 455, -161, 444, 445, 456, 450, 451, 517, 519, 520, + -1000, -422, -80, -427, -7, -29, -15, -16, -17, -18, + -19, -20, -21, -22, -23, -24, -25, -26, -65, -68, + -66, -67, -70, -71, -72, -73, -74, -9, -11, -69, + -27, -28, -75, -76, -77, -78, -79, -12, -13, -14, + -8, -32, -31, -30, 13, 14, -110, -36, 35, -41, + -51, 240, -52, -42, 241, -53, 243, 242, 280, 244, + 397, 273, 83, 330, 331, 333, 334, 335, 336, -111, + 708, 278, 279, 246, 39, 51, 36, 37, 40, 250, + 286, 287, 249, 145, -33, -37, 12, -424, 15, 487, + 275, 274, 31, -34, 597, 95, -35, 63, -81, -423, + 756, -258, -242, 26, 36, 32, -241, -237, -129, -242, + 24, 22, 11, -80, -80, -80, 16, 17, -80, -361, + -363, 95, 173, 95, -80, -58, -57, -55, -54, -56, + -59, 34, -48, -49, -385, -47, -44, 245, 242, 290, + 135, 136, 280, 281, 282, 244, 264, 279, 283, 278, + 299, -43, 90, 36, 597, 600, -368, 241, 247, 248, + 243, 488, 138, 137, 84, -365, 392, 631, 726, -59, + 728, 110, 113, 727, 50, 254, 729, 730, 731, 638, + 732, 263, 733, 734, 735, 736, 742, 679, 743, 744, + 745, 139, 11, -80, -310, -306, 100, -299, 594, 266, + 629, 441, 630, 315, 90, 47, 42, 533, 604, 388, + 392, 631, 518, 726, 398, 330, 348, 342, 523, 524, + 525, 371, 363, 595, 632, 605, 318, 267, 303, 720, + 361, 149, 728, 322, 633, 281, 399, 400, 634, 401, + 110, 333, 438, 741, 321, 635, 739, 113, 727, 338, + 88, 517, 57, 723, 326, 50, 276, 446, 447, 359, + 249, 355, 729, 304, 636, 607, 297, 138, 135, 748, + 39, 351, 56, 33, 738, 137, 55, 730, 164, 637, + 731, 638, 403, 378, 714, 54, 404, 282, 639, 93, + 287, 599, 327, 722, 405, 538, 352, 406, 314, 737, + 246, 640, 325, 703, 695, 696, 407, 408, 715, 383, + 379, 384, 540, 641, 430, 522, 409, 699, 700, 755, + 58, 642, 643, 716, 136, 644, 87, 732, 89, 346, + 347, 645, 312, 265, 543, 544, 432, 375, 500, 127, + 507, 508, 120, 121, 503, 122, 509, 123, 128, 510, + 511, 512, 501, 124, 117, 502, 513, 514, 376, 377, + 125, 515, 119, 118, 504, 506, 126, 516, 263, 38, + 410, 596, 316, 64, 320, 291, 433, 52, 381, 752, + 51, 710, 545, 646, 713, 374, 370, 497, 691, 59, + 647, 648, 649, 650, 519, 733, 373, 345, 369, 747, + 4, 309, 492, 520, 734, 68, 248, 386, 385, 387, + 298, 429, 366, 651, 652, 653, 270, 91, 654, 356, + 25, 655, 656, 411, 305, 657, 62, 658, 659, 436, + 279, 660, 60, 735, 692, 45, 661, 284, 749, 736, + 662, 663, 664, 709, 665, 286, 666, 413, 667, 697, + 698, 412, 380, 382, 546, 293, 414, 397, 693, 251, + 598, 668, 328, 350, 283, 740, 669, 271, 534, 535, + 536, 537, 721, 542, 541, 285, 290, 278, 437, 272, + 670, 671, 672, 673, 674, 319, 690, 675, 676, 334, + 602, 742, 498, 49, 677, 678, 679, 680, 681, 313, + 308, 431, 440, 67, 92, 394, 682, 683, 719, 344, + 339, 43, 306, 99, 478, 480, 481, 482, 483, 484, + 479, 486, 684, 331, 61, 743, 744, 745, 300, 746, + 526, 527, 528, 529, 13, 580, 563, 591, 564, 581, + 565, 574, 566, 582, 590, 592, 547, 555, 548, 556, + 586, 569, 583, 575, 568, 567, 589, 572, 576, 549, + 557, 587, 573, 550, 558, 551, 559, 552, 560, 585, + 584, 577, 588, 553, 561, 579, 554, 562, 578, 570, + 571, 449, 753, 754, 521, 416, 694, 139, 310, 311, + 53, 367, 292, 685, 323, 686, 357, 358, 494, 495, + 372, 343, 368, 146, 706, 332, 341, 704, 294, 417, + 499, 280, 687, 439, 307, 389, 131, 340, 395, 324, + 603, 539, 299, 418, 718, 601, 530, 531, 365, 362, + 301, 532, 688, 390, 708, 419, 255, 295, 296, 689, + 705, 420, 421, 317, 422, 423, 424, 425, 426, 428, + 329, 427, 707, 701, 702, 302, 477, 600, 337, 360, + 396, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 496, + 253, -80, 253, -191, -306, -131, 710, 712, 192, -277, + 400, -295, 402, 415, 410, 420, 408, -286, 411, 413, + 293, -408, 430, 253, 417, 240, 403, 412, 421, 422, + 317, 428, 423, 329, 427, 302, 424, 425, 426, -392, + 192, 731, 746, 332, 340, 149, 364, 407, 405, 431, + 710, 100, -312, 100, 101, 102, -299, 332, -315, 337, + -300, -392, -299, 335, -80, -80, -317, -317, -131, -211, + -146, 157, -160, -266, -163, 101, -151, -154, -205, -206, + -207, -208, -161, -225, -264, 181, 182, 189, 158, -221, + -164, 29, 593, 489, 488, 192, 34, 235, 77, 78, + 491, 492, 160, 63, 15, 454, 455, -162, 444, 445, + 456, 450, 451, 517, 519, 520, 521, 518, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 522, 533, + 494, 495, 129, 496, 117, 119, 118, 127, 128, 497, + 498, 499, 361, 545, 546, 540, 543, 544, 542, 541, + 376, 377, 500, 563, 564, 568, 567, 565, 566, 569, + 572, 573, 574, 575, 576, 577, 579, 578, 570, 571, + 548, 547, 549, 550, 551, 552, 553, 554, 556, 555, + 557, 558, 559, 560, 561, 562, 580, 581, 582, 583, + 584, 586, 585, 590, 589, 587, 588, 592, 591, 501, + 502, 120, 121, 122, 123, 124, 125, 126, 503, 506, + 504, 505, 507, 508, 509, 514, 515, 510, 511, 512, + 513, 516, 387, 385, 386, 382, 381, 380, -90, -103, + 620, 619, -104, 441, 446, 447, 449, -152, -153, -166, + -167, -300, -306, 258, 443, 252, 187, 487, -155, -149, + -223, 116, 102, -31, -220, 442, 452, 453, 457, 448, + 458, 606, 608, 623, 624, 626, 611, 616, 615, 618, + 534, 535, 536, 537, 538, 539, 695, 696, 697, 698, + 699, 700, 701, 702, -392, -299, 100, -158, -156, -200, + 103, 108, 111, 112, 114, -414, 276, 357, 358, 130, + -424, -216, -217, -157, 105, 106, 107, 132, 133, 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, 227, 228, 229, 230, 231, 232, 233, + 234, 724, 98, 104, 50, 416, 416, -191, -80, -80, + -80, -80, -421, 727, 598, -235, -129, -237, -33, -31, + -424, 12, -80, -31, -32, -30, -37, -39, 625, -38, + -306, -80, 109, -242, -258, 16, 67, 176, 48, 56, + -240, -241, -34, -31, -146, 23, 41, 27, -133, 183, + -146, -306, -133, -284, 257, -80, -80, -273, -320, 332, + -275, 431, 710, 430, -265, -278, 100, -264, -277, 429, + 101, -362, 173, -348, -352, -300, 268, -378, 264, -191, + -371, -370, -300, -424, -130, -294, 254, 262, 261, 150, + -395, 153, 310, 443, 252, -54, -55, -56, -277, 191, + 730, -112, 285, 289, 96, 96, -352, -351, -350, -396, + 289, 268, -377, -369, 260, 269, -358, 261, 262, -353, + 254, 151, -396, -353, 259, 269, 264, 268, 289, 289, + 139, 289, 139, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 284, -359, 165, -359, 601, 601, -365, -396, + 264, 254, -396, -396, 260, -296, -353, 256, 28, 256, + 38, 38, -359, -359, -359, -277, 191, -359, -359, -359, + -359, 297, 297, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, -359, -359, + 253, -395, -138, 427, 317, 90, -57, 299, -40, -191, + -294, 254, 255, -395, 286, -191, 236, 253, 713, -288, + 173, 19, -288, -285, 416, 414, 401, 406, -288, -288, + -288, -288, 300, 399, -354, 254, 38, 265, 416, 300, + 399, 300, 301, 300, 301, 409, 419, 300, -311, 18, + 176, 443, 404, 408, 293, 253, 294, 255, 418, 301, + -311, 98, -289, 173, 300, 416, 410, 296, -288, -288, + -318, -424, -302, -300, -298, 245, 41, 156, 28, 30, + 159, 192, 142, 23, 160, 40, 247, 364, 264, 191, + 260, 488, 240, 81, 606, 444, 451, 442, 450, 454, + 490, 491, 443, 402, 34, 17, 608, 31, 274, 27, + 44, 185, 242, 163, 609, 277, 29, 275, 129, 133, + 611, 26, 84, 269, 18, 262, 46, 20, 612, 613, + 21, 74, 258, 257, 176, 254, 79, 15, 235, 32, + 172, 75, 614, 151, 145, 615, 616, 617, 618, 143, + 77, 173, 24, 750, 452, 453, 36, 711, 593, 288, + 187, 82, 65, 712, 157, 448, 619, 620, 130, 621, + 134, 85, 717, 153, 22, 80, 48, 622, 289, 623, + 259, 751, 624, 434, 625, 174, 243, 487, 78, 175, + 724, 626, 725, 252, 415, 12, 493, 35, 273, 261, + 73, 72, 141, 76, 458, 627, 253, 162, 256, 144, + 132, 11, 150, 37, 16, 83, 86, 455, 456, 457, + 63, 140, 597, 161, 19, 628, 435, 155, -392, 713, + -318, -318, 300, 341, 35, 101, -418, -419, -420, 597, + 434, 256, -300, -191, -86, 703, 244, -87, 709, 41, + 251, 146, 38, -136, 416, -124, 192, 731, 714, 715, + 716, 713, 413, 721, 719, 717, 300, 718, 96, 153, + 155, 156, 4, -146, 172, -201, -202, 171, 165, 166, + 167, 168, 169, 170, 177, 176, 157, 159, 173, -251, + 154, 178, 179, 180, 181, 182, 183, 184, 186, 185, + 187, 188, 174, 175, 191, 238, 239, -154, -154, -154, + -154, -221, -227, -226, -424, -223, -392, -299, -306, -424, + -424, -154, -283, -424, -151, -424, -424, -424, -424, -424, + -230, -146, -424, -424, -428, -424, -428, -428, -428, -337, + -424, -337, -337, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, 236, -424, + -424, -424, -424, -424, -337, -337, -337, -337, -337, -337, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, 98, 112, 108, 111, 103, 114, + 98, 98, 98, 98, -31, -32, -211, 63, -424, -317, + -405, -406, -194, -191, -424, 317, -300, -300, 286, 105, + -240, -34, -31, -235, -241, -237, -31, -80, -122, -135, + 69, 70, -134, -137, 27, 44, 74, 76, 99, 72, + 73, 71, 41, -425, 97, -425, -258, -425, 96, -39, + -261, 95, 115, -214, -219, -217, 724, 653, 683, 653, + 683, 67, 49, 98, 98, 96, 25, -236, -238, -146, + 18, -304, 4, -303, 28, -300, 98, 236, 18, -192, + 32, -191, -284, -284, 96, 100, 332, -274, -276, 432, + 434, 165, -305, -300, 98, 34, 97, 96, -191, -326, + -329, -331, -330, -332, -327, -328, 361, 362, 192, 365, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 378, + 390, 35, 276, 357, 358, 359, 360, 379, 380, 381, + 382, 384, 385, 386, 387, 342, 363, 595, 343, 344, + 345, 346, 347, 348, 350, 351, 354, 352, 353, 355, + 356, -301, -300, 95, 97, 96, -336, 95, -146, -138, + 253, -300, 254, 254, 254, -291, 258, 487, -359, -359, + -359, 284, 23, -47, -44, -385, 22, -43, -44, 245, + 135, 136, 242, 95, -348, 95, -357, -301, -300, 95, + 151, 259, 150, -356, -353, -356, -357, -300, -223, -300, + 151, 151, -300, -300, -270, -300, -270, -270, 41, -270, + 41, -270, 41, 105, -300, -270, 41, -270, 41, -270, + 41, -270, 41, -270, 41, 34, 87, 88, 89, 34, + 91, 92, 93, -223, -300, -300, -223, -348, -223, -191, + -300, -277, 105, 105, 105, -359, -359, 105, 98, 98, + 98, -359, -359, 105, 98, -308, -306, 98, 98, -397, + 270, 314, 316, 105, 105, 105, 105, 34, 98, -398, + 34, 738, 737, 739, 740, 741, 98, 105, 34, 105, + 34, 105, -300, 95, -191, -144, 304, 240, 242, 245, + 85, 98, 322, 320, 321, 318, 323, 324, 325, 165, + 50, 96, 256, 253, -300, -290, 258, -290, -300, -307, + -306, -298, -191, 256, 398, 98, -146, -355, 18, 176, + -311, -311, -288, -191, -355, -311, -288, -191, -288, -288, + -288, -288, -311, -311, -311, -288, -306, -306, -191, -191, + -191, -191, -191, -191, -191, -318, -289, -288, 713, 98, + -282, 18, 85, -318, -318, -297, 26, 26, 96, 338, + 435, 436, -316, 335, -82, -300, 98, -10, -29, -18, + -17, -19, 165, -10, 96, 597, -184, -191, 713, 713, + 713, 713, 713, 713, -146, -146, -146, -146, 621, -209, + -416, 157, 132, 133, 130, 131, -163, 42, 43, 41, + -146, -210, -216, -221, 115, 176, 159, 173, -251, -151, + -154, -151, -151, -151, -151, -151, -151, 235, -151, 235, + -151, -151, -151, -151, -151, -151, -319, -300, 98, 192, + -159, -158, 114, -414, -159, 594, 96, -226, 236, -146, + -146, -392, -120, 460, 461, 462, 463, 465, 466, 467, + 470, 471, 475, 476, 459, 477, 464, 469, 472, 473, + 474, 468, 360, -146, -212, -211, -212, -146, -146, -228, + -229, 161, -223, -146, -425, -425, 105, 183, -128, 27, + 44, -128, -128, -128, -128, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -128, -146, -121, 459, 477, + 464, 469, 472, 473, 474, 468, 360, 478, 479, 480, + 481, 482, 483, 484, 485, 486, -121, -120, -146, -146, + -146, -146, -146, -146, -146, -146, -88, -146, 142, 143, + 144, -211, -146, -151, -146, -146, -146, -425, -146, -146, + -146, -212, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -391, -390, + -389, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -211, -211, -211, -211, -211, -146, + -425, -146, -165, -149, 105, -266, 114, 101, -146, -146, + -146, -146, -146, -146, -212, -302, -307, -298, -299, -211, + -212, -212, -211, -211, -146, -146, -146, -146, -146, -146, + -146, -146, -425, -146, -146, -146, -146, -146, -258, -425, + -211, 96, -407, 434, 435, 711, -309, 289, -308, 28, + -212, 98, 18, -268, 86, -300, -240, -240, 69, 70, + 65, -132, -133, -137, -425, -38, 28, -260, -300, 96, + -424, 646, 646, 68, 98, -338, -277, 388, 389, 192, + -146, -146, 96, -239, 30, 31, -191, -303, 183, -307, + -191, -269, 289, -191, -169, -171, -172, -173, -194, -222, + -424, -174, -31, 617, 614, 18, -184, -185, -193, -306, + -275, -320, -274, 96, 433, 435, 436, 85, 134, -146, + -339, 191, -367, -366, -365, -348, -350, -351, -352, 97, + -339, -344, 395, 394, -336, -336, -336, -336, -336, -338, + -338, -338, -338, 95, -336, 95, -336, -336, -336, -336, + -341, 95, -341, -341, -342, -341, 95, -342, -343, 95, + -343, -378, -146, -375, -374, -372, -373, 263, 110, 689, + 645, 597, 638, 679, 86, -370, -239, 105, -425, -144, + -291, -376, -373, -300, -300, -300, -306, 157, 100, 98, + 100, 98, 100, 98, -113, -61, -1, 750, 751, 752, + 96, 23, -349, -348, -60, 314, -381, -382, 289, -377, + -371, -357, 151, -356, -357, -357, -300, 96, 32, 139, + 139, 139, 139, 597, 242, 35, -292, 637, 157, 689, + 645, -348, -60, 256, 256, -319, -319, -319, 98, 98, + -287, 746, -184, -140, 306, 165, 295, 295, 253, 308, + 253, 308, -191, 319, 322, 320, 321, 318, 323, 324, + 325, 326, 41, 41, 41, 41, 41, 41, 41, 307, + 309, 311, 297, -191, -191, -290, 85, -186, -191, 29, + -306, 98, 98, -191, -288, -288, -191, -288, -288, -191, + 98, -306, -420, 339, -300, 375, 704, 706, -124, 434, + 96, 597, 26, -125, 26, -424, -416, 132, 133, -221, + -221, -221, -210, -151, -154, -151, 156, 277, -151, -151, + -424, -223, -425, -302, 28, 96, 86, -425, 181, 96, + -425, -425, 96, 18, 96, -231, -229, 163, -146, -425, + 96, -425, -425, -211, -146, -146, -146, -146, -425, -425, + -425, -425, -425, -425, -425, -425, -425, -425, -211, -425, + 96, 96, 18, -323, 28, -425, -425, -425, -425, 96, + -425, -425, -230, -425, 18, -425, 86, 96, 176, 96, + -425, -425, -425, 96, 96, -425, -425, 96, -425, 96, + -425, -425, -425, -425, -425, -425, 96, -425, 96, -425, + -425, -425, 96, -425, 96, -425, -425, 96, -425, 96, + -425, 96, -425, 96, -425, 96, -425, 96, -425, 96, + -425, 96, -425, 96, -425, 96, -425, 96, -425, 96, + -425, 96, -425, 96, -425, 96, -425, 96, -425, 96, + -425, 96, -425, -425, -425, 96, -425, 96, -425, 96, + -425, -425, 96, -425, 96, -425, 96, -425, 96, 96, + -425, 96, 96, 96, -425, 96, 96, 96, 96, -425, + -425, -425, -425, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, -425, -425, -425, -425, -425, -425, 96, + -95, 622, -425, -425, 96, -425, 96, 96, 96, 96, + 96, -425, -424, 236, -425, -425, -425, -425, -425, 96, + 96, 96, 96, 96, 96, -425, -425, -425, 96, 96, + -425, 96, -425, 96, -425, -406, 710, 435, -198, -197, + -195, 83, 257, 84, -424, -308, -425, -159, -266, -267, + -266, -204, -300, 105, 114, -242, -168, 96, -170, 18, + -221, 97, 96, -219, -425, -338, -246, -252, -285, -300, + 98, 192, -340, 192, -340, 388, 389, -238, 236, -199, + 19, -203, 35, 63, -29, -424, -424, 35, 96, -187, + -189, -188, -190, 75, 79, 81, 76, 77, 78, 82, + -314, 28, -31, -169, -31, -424, -191, -184, -426, 18, + 86, -426, 96, 236, -276, -279, 437, 434, 440, -392, + 98, -112, 96, -365, -352, -243, -141, 46, -345, 396, + -338, 605, -338, -347, 98, -347, 105, 105, 105, 97, + -50, -45, -46, 36, 90, -372, -359, 98, 45, -359, + -359, -300, 97, -239, -140, -191, 85, -376, -376, -376, + 29, -2, 749, 755, 151, 95, 401, 22, -260, 96, + 97, -224, 315, 97, -114, -300, 97, 95, -357, -357, + -300, -424, 253, 34, 34, 689, 645, 637, -60, -224, + -223, -300, -339, 748, 747, 97, 255, 313, -145, 454, + -142, 98, 100, -191, -191, -191, -191, -191, -191, 245, + 242, 424, -415, 327, 98, -415, 298, 256, -184, -191, + 96, -85, 272, 267, -311, -311, 36, -191, 434, 722, + 720, -146, 156, 277, -163, -154, -120, -120, -151, -321, + 192, 361, 276, 359, 355, 375, 366, 394, 357, 395, + 352, 351, 350, -321, -319, -151, -211, -146, -146, -146, + 164, -146, 162, -146, -96, -95, -425, -425, -425, -425, + -425, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -235, -146, -146, -146, -425, 192, 361, -96, -146, + 18, -146, -319, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -389, -146, + -211, -146, -211, -146, -146, -146, -146, -146, -390, -390, + -390, -390, -390, -211, -211, -211, -211, -146, -424, -300, + -99, -98, -97, 672, 257, -95, -165, -99, -165, 235, + -146, 235, 235, 235, -146, -212, -302, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -195, -353, 295, + -353, 295, -353, -270, 96, -281, 26, 18, 63, 63, + -168, -199, -133, -169, -300, -249, 703, -255, 52, -253, + -254, 53, -250, 54, 62, -340, -340, 183, -240, -146, + -271, 85, -272, -280, -223, -215, -218, -216, -424, -259, + -425, -300, -270, -272, -171, -172, -172, -171, -172, 75, + 75, 75, 80, 75, 80, 75, -188, -306, -425, -146, + -309, 86, -169, -169, -193, -306, 183, 434, 438, 439, + -365, -413, 130, 157, 34, 85, 392, 110, -411, 191, + 634, 684, 689, 645, 638, 679, -412, 259, 150, 151, + 271, 28, 47, 97, 96, 97, 96, 97, 97, 96, + -293, -292, -46, -45, -359, -359, 105, -392, 98, 98, + 255, -191, 85, 85, 85, -115, 753, 105, 95, -3, + 90, -146, 95, 23, -348, -223, -383, -333, -384, -334, + -335, -5, -6, -360, -118, 63, 110, -64, 50, 254, + 733, 734, 139, -424, 746, -375, -260, -379, -381, -191, + -150, -424, -162, -148, -147, -149, -155, 181, 182, 276, + 357, 358, -224, -191, -139, 304, 312, 95, -143, 101, + -394, 86, 295, 392, 295, 392, 98, -417, 328, 98, + -417, -191, -85, -50, -191, -288, -288, 36, -392, -425, + -163, -154, -127, 176, 597, -324, 604, -336, -336, -336, + -343, -336, 347, -336, 347, -336, -425, -425, -425, 96, + -425, 26, -425, 96, -146, 96, -96, -96, -96, -96, + -96, -123, 493, 96, 96, -425, 95, 95, -425, -146, + -425, -425, -425, 96, -425, -425, -425, -425, -425, -425, + -425, -425, -425, -425, -425, -425, -425, 96, -425, 96, + -425, 96, -425, 96, -425, 96, -425, 96, -425, 96, + -425, 96, -425, 96, -425, 96, -425, 96, -425, 96, + -425, 96, -425, 96, -425, 96, -425, 96, -425, -425, + 96, -425, -425, -425, 96, -425, 96, -425, 96, -425, + -425, -425, 96, -322, 690, -425, -425, -425, -425, -425, + -425, -425, -425, -425, -425, -425, -94, -301, -95, 654, + 654, -425, -95, -232, 96, -151, -425, -151, -151, -151, + -425, -425, -425, 96, -425, 96, 96, -425, 96, -425, + 96, -425, -425, -425, -425, 96, -196, 26, -424, -196, + -424, -196, -425, -266, -191, -199, -233, 20, -246, 57, + 367, -257, -256, 61, 53, -254, 23, 55, 23, 33, + -271, 96, 165, -313, 96, 28, -425, -425, 96, 63, + 236, -425, -199, -182, -181, 85, 86, -183, 85, -181, + 75, 75, -261, 96, -269, -169, -199, -199, 236, 130, + -424, -150, 16, 98, 98, -392, -410, 737, 738, 34, + 105, -359, -359, 151, 151, -191, 95, -338, 98, -338, + 105, 105, 34, 91, 92, 93, 34, 87, 88, 89, + -191, -191, -191, -191, -380, 95, 23, -146, 95, 165, + 97, -260, -260, 291, 176, -359, 731, 297, 297, -359, + -359, -359, -117, -116, 753, 97, -425, 96, -346, 597, + 600, -146, -156, -156, -261, 97, -388, 597, -393, -300, + -300, -300, -300, 105, 107, -425, 595, 82, 598, -425, + -338, -146, -146, -146, -146, -240, 98, -146, -146, 105, + 105, -96, -425, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, -211, -146, -425, -179, -178, -180, 714, + 130, 34, -321, -425, -213, 289, -102, -101, -100, 18, + -425, -146, -120, -120, -120, -120, -146, -146, -146, -146, + -146, -146, -424, 75, 22, 20, -263, -300, 259, -424, + -263, -424, -309, -233, -234, 21, 23, -247, 59, -245, + 58, -245, -256, 23, 23, 98, 23, 98, 151, -280, + -146, -218, -308, 63, -29, -300, -215, -300, -235, -146, + 95, -146, -159, -199, -199, -146, -206, 517, 519, 520, 521, 518, 523, 524, 525, 526, 527, 528, 529, 530, - 531, 532, 522, 533, 494, 495, 129, 496, 117, 119, - 118, 127, 128, 497, 498, 499, 361, 545, 546, 540, - 543, 544, 542, 541, 376, 377, 500, 563, 564, 568, - 567, 565, 566, 569, 572, 573, 574, 575, 576, 577, - 579, 578, 570, 571, 548, 547, 549, 550, 551, 552, - 553, 554, 556, 555, 557, 558, 559, 560, 561, 562, - 580, 581, 582, 583, 584, 586, 585, 590, 589, 587, - 588, 592, 591, 501, 502, 120, 121, 122, 123, 124, - 125, 126, 503, 506, 504, 505, 507, 508, 509, 514, - 515, 510, 511, 512, 513, 516, 387, 385, 386, 382, - 381, 380, -89, -102, 620, 619, -103, 441, 446, 447, - 449, -151, -152, -165, -166, -295, -301, 258, 443, 252, - 187, 487, -154, -148, -218, 116, 102, -31, -214, 442, - 452, 453, 457, 448, 458, 606, 608, 623, 624, 626, - 611, 616, 615, 618, 534, 535, 536, 537, 538, 539, - 691, 692, 693, 694, 695, 696, 697, 698, -387, -294, - 100, -157, -155, -199, 103, 108, 111, 112, 114, -409, - 276, 357, 358, 130, -419, 720, -156, 105, 106, 107, - 132, 133, 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, 227, 228, 229, 230, - 231, 232, 233, 234, 98, 104, 50, 416, 416, -190, - -79, -79, -79, -79, -416, 723, 598, -230, -128, -232, - -33, -31, -419, 12, -79, -31, -32, -30, -36, -38, - 625, -37, -301, 109, -237, -253, 16, 67, 176, 48, - 56, -235, -236, -34, -31, -145, 23, 41, 27, -132, - 183, -145, -301, -132, -279, 257, -79, -79, -268, -315, - 332, -270, 431, 706, 430, -260, -273, 100, -259, -272, - 429, 101, -357, 173, -343, -347, -295, 268, -373, 264, - -190, -366, -365, -295, -419, -129, -289, 254, 262, 261, - 150, -390, 153, 310, 443, 252, -53, -54, -55, -272, - 191, 726, -111, 285, 289, 96, 96, -347, -346, -345, - -391, 289, 268, -372, -364, 260, 269, -353, 261, 262, - -348, 254, 151, -391, -348, 259, 269, 264, 268, 289, - 289, 139, 289, 139, 289, 289, 289, 289, 289, 289, - 289, 289, 289, 284, -354, 165, -354, 601, 601, -360, - -391, 264, 254, -391, -391, 260, -291, -348, 256, 28, - 256, 38, 38, -354, -354, -354, -272, 191, -354, -354, - -354, -354, 297, 297, -354, -354, -354, -354, -354, -354, - -354, -354, -354, -354, -354, -354, -354, -354, -354, -354, - -354, 253, -390, -137, 427, 317, 90, -56, 299, -39, - -190, -289, 254, 255, -390, 286, -190, 236, 253, 709, - -283, 173, 19, -283, -280, 416, 414, 401, 406, -283, - -283, -283, -283, 300, 399, -349, 254, 38, 265, 416, - 300, 399, 300, 301, 300, 301, 409, 419, 300, -306, - 18, 176, 443, 404, 408, 293, 253, 294, 255, 418, - 301, -306, 98, -284, 173, 300, 416, 410, 296, -283, - -283, -313, -419, -297, -295, -293, 245, 41, 156, 28, - 30, 159, 192, 142, 23, 160, 40, 247, 364, 264, - 191, 260, 488, 240, 81, 606, 444, 451, 442, 450, - 454, 490, 491, 443, 402, 34, 17, 608, 31, 274, - 27, 44, 185, 242, 163, 609, 277, 29, 275, 129, - 133, 611, 26, 84, 269, 18, 262, 46, 20, 612, - 613, 21, 74, 258, 257, 176, 254, 79, 15, 235, - 32, 172, 75, 614, 151, 145, 615, 616, 617, 618, - 143, 77, 173, 24, 746, 452, 453, 36, 707, 593, - 288, 187, 82, 65, 708, 157, 448, 619, 620, 130, - 621, 134, 85, 713, 153, 22, 80, 48, 622, 289, - 623, 259, 747, 624, 434, 625, 174, 243, 487, 78, - 175, 720, 626, 721, 252, 415, 12, 493, 35, 273, - 261, 73, 72, 141, 76, 458, 627, 253, 162, 256, - 144, 132, 11, 150, 37, 16, 83, 86, 455, 456, - 457, 63, 140, 597, 161, 19, 628, 435, 155, -387, - 709, -313, -313, 300, 341, 35, 101, -413, -414, -415, - 597, 434, 256, -295, -190, -85, 699, 244, -86, 705, - 41, 251, 146, 38, -135, 416, -123, 192, 727, 710, - 711, 712, 709, 413, 717, 715, 713, 300, 714, 96, - 153, 155, 156, 4, -145, 172, -200, -201, 171, 165, - 166, 167, 168, 169, 170, 177, 176, 157, 159, 173, - -246, 154, 178, 179, 180, 181, 182, 183, 184, 186, - 185, 187, 188, 174, 175, 191, 238, 239, -153, -153, - -153, -153, -216, -222, -221, -419, -218, -387, -294, -301, - -419, -419, -153, -278, -419, -150, -419, -419, -419, -419, - -419, -225, -145, -419, -419, -423, -419, -423, -423, -423, - -332, -419, -332, -332, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, -419, -419, -419, -419, 236, - -419, -419, -419, -419, -419, -332, -332, -332, -332, -332, - -332, -419, -419, -419, -419, -419, -419, -419, -419, -419, - -419, -419, -419, -419, -419, 98, 112, 108, 111, 103, - 114, 98, 98, 98, 98, -31, -32, -210, -419, -312, - -400, -401, -193, -190, -419, 317, -295, -295, 286, 105, - -235, -34, -31, -230, -236, -232, -31, -79, -121, -134, - 69, 70, -133, -136, 27, 44, 74, 76, 99, 72, - 73, 71, 41, -420, 97, -420, -253, -420, 96, -38, - -256, 95, 653, 683, 653, 683, 67, 49, 98, 98, - 96, 25, -231, -233, -145, 18, -299, 4, -298, 28, - -295, 98, 236, 18, -191, 32, -190, -279, -279, 96, - 100, 332, -269, -271, 432, 434, 165, -300, -295, 98, - 34, 97, 96, -190, -321, -324, -326, -325, -327, -322, - -323, 361, 362, 192, 365, 367, 368, 369, 370, 371, - 372, 373, 374, 375, 378, 390, 35, 276, 357, 358, - 359, 360, 379, 380, 381, 382, 384, 385, 386, 387, - 342, 363, 595, 343, 344, 345, 346, 347, 348, 350, - 351, 354, 352, 353, 355, 356, -296, -295, 95, 97, - 96, -331, 95, -145, -137, 253, -295, 254, 254, 254, - -286, 258, 487, -354, -354, -354, 284, 23, -46, -43, - -380, 22, -42, -43, 245, 135, 136, 242, 95, -343, - 95, -352, -296, -295, 95, 151, 259, 150, -351, -348, - -351, -352, -295, -218, -295, 151, 151, -295, -295, -265, - -295, -265, -265, 41, -265, 41, -265, 41, 105, -295, - -265, 41, -265, 41, -265, 41, -265, 41, -265, 41, - 34, 87, 88, 89, 34, 91, 92, 93, -218, -295, - -295, -218, -343, -218, -190, -295, -272, 105, 105, 105, - -354, -354, 105, 98, 98, 98, -354, -354, 105, 98, - -303, -301, 98, 98, -392, 270, 314, 316, 105, 105, - 105, 105, 34, 98, -393, 34, 734, 733, 735, 736, - 737, 98, 105, 34, 105, 34, 105, -295, 95, -190, - -143, 304, 240, 242, 245, 85, 98, 322, 320, 321, - 318, 323, 324, 325, 165, 50, 96, 256, 253, -295, - -285, 258, -285, -295, -302, -301, -293, -190, 256, 398, - 98, -145, -350, 18, 176, -306, -306, -283, -190, -350, - -306, -283, -190, -283, -283, -283, -283, -306, -306, -306, - -283, -301, -301, -190, -190, -190, -190, -190, -190, -190, - -313, -284, -283, 709, 98, -277, 18, 85, -313, -313, - -292, 26, 26, 96, 338, 435, 436, -311, 335, -81, - -295, 98, -10, -29, -18, -17, -19, 165, -10, 96, - 597, -183, -190, 709, 709, 709, 709, 709, 709, -145, - -145, -145, -145, 621, -208, -411, 157, 132, 133, 130, - 131, -162, 42, 43, 41, -145, -209, -214, -216, 115, - 176, 159, 173, -246, -150, -153, -150, -150, -150, -150, - -150, -150, 235, -150, 235, -150, -150, -150, -150, -150, - -150, -314, -295, 98, 192, -158, -157, 114, -409, -158, - 594, 96, -221, 236, -145, -145, -387, -119, 460, 461, - 462, 463, 465, 466, 467, 470, 471, 475, 476, 459, - 477, 464, 469, 472, 473, 474, 468, 360, -145, -211, - -210, -211, -145, -145, -223, -224, 161, -218, -145, -420, - -420, 105, 183, -127, 27, 44, -127, -127, -127, -127, - -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -127, -145, -120, 459, 477, 464, 469, 472, 473, 474, - 468, 360, 478, 479, 480, 481, 482, 483, 484, 485, - 486, -120, -119, -145, -145, -145, -145, -145, -145, -145, - -145, -87, -145, 142, 143, 144, -210, -145, -150, -145, - -145, -145, -420, -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, -145, -145, -145, - -145, -145, -145, -386, -385, -384, -145, -145, -145, -145, - -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -145, -145, -145, -145, -145, -145, -145, -145, -145, -210, - -210, -210, -210, -210, -145, -420, -145, -164, -148, 105, - -261, 114, 101, -145, -145, -145, -145, -145, -145, -211, - -297, -302, -293, -294, -210, -211, -211, -210, -210, -145, - -145, -145, -145, -145, -145, -145, -145, -420, -145, -145, - -145, -145, -145, -253, -420, -210, 96, -402, 434, 435, - 707, -304, 289, -303, 28, -211, 98, 18, -263, 86, - -295, -235, -235, 69, 70, 65, -131, -132, -136, -420, - -37, 28, -255, -295, 646, 646, 68, 98, -333, -272, - 388, 389, 192, -145, -145, 96, -234, 30, 31, -190, - -298, 183, -302, -190, -264, 289, -190, -168, -170, -171, - -172, -193, -217, -419, -173, -31, 617, 614, 18, -183, - -184, -192, -301, -270, -315, -269, 96, 433, 435, 436, - 85, 134, -145, -334, 191, -362, -361, -360, -343, -345, - -346, -347, 97, -334, -339, 395, 394, -331, -331, -331, - -331, -331, -333, -333, -333, -333, 95, -331, 95, -331, - -331, -331, -331, -336, 95, -336, -336, -337, -336, 95, - -337, -338, 95, -338, -373, -145, -370, -369, -367, -368, - 263, 110, 689, 645, 597, 638, 679, 86, -365, -234, - 105, -420, -143, -286, -371, -368, -295, -295, -295, -301, - 157, 100, 98, 100, 98, 100, 98, -112, -60, -1, - 746, 747, 748, 96, 23, -344, -343, -59, 314, -376, - -377, 289, -372, -366, -352, 151, -351, -352, -352, -295, - 96, 32, 139, 139, 139, 139, 597, 242, 35, -287, - 637, 157, 689, 645, -343, -59, 256, 256, -314, -314, - -314, 98, 98, -282, 742, -183, -139, 306, 165, 295, - 295, 253, 308, 253, 308, -190, 319, 322, 320, 321, - 318, 323, 324, 325, 326, 41, 41, 41, 41, 41, - 41, 41, 307, 309, 311, 297, -190, -190, -285, 85, - -185, -190, 29, -301, 98, 98, -190, -283, -283, -190, - -283, -283, -190, 98, -301, -415, 339, -295, 375, 700, - 702, -123, 434, 96, 597, 26, -124, 26, -419, -411, - 132, 133, -216, -216, -216, -209, -150, -153, -150, 156, - 277, -150, -150, -419, -218, -420, -297, 28, 96, 86, - -420, 181, 96, -420, -420, 96, 18, 96, -226, -224, - 163, -145, -420, 96, -420, -420, -210, -145, -145, -145, - -145, -420, -420, -420, -420, -420, -420, -420, -420, -420, - -420, -210, -420, 96, 96, 18, -318, 28, -420, -420, - -420, -420, 96, -420, -420, -225, -420, 18, -420, 86, - 96, 176, 96, -420, -420, -420, 96, 96, -420, -420, - 96, -420, 96, -420, -420, -420, -420, -420, -420, 96, - -420, 96, -420, -420, -420, 96, -420, 96, -420, -420, - 96, -420, 96, -420, 96, -420, 96, -420, 96, -420, - 96, -420, 96, -420, 96, -420, 96, -420, 96, -420, - 96, -420, 96, -420, 96, -420, 96, -420, 96, -420, - 96, -420, 96, -420, 96, -420, -420, -420, 96, -420, - 96, -420, 96, -420, -420, 96, -420, 96, -420, 96, - -420, 96, 96, -420, 96, 96, 96, -420, 96, 96, - 96, 96, -420, -420, -420, -420, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, -420, -420, -420, -420, - -420, -420, 96, -94, 622, -420, -420, 96, -420, 96, - 96, 96, 96, 96, -420, -419, 236, -420, -420, -420, - -420, -420, 96, 96, 96, 96, 96, 96, -420, -420, - -420, 96, 96, -420, 96, -420, 96, -420, -401, 706, - 435, -197, -196, -194, 83, 257, 84, -419, -303, -420, - -158, -261, -262, -261, -203, -295, 105, 114, -237, -167, - 96, -169, 18, -216, 97, 96, -333, -241, -247, -280, - -295, 98, 192, -335, 192, -335, 388, 389, -233, 236, - -198, 19, -202, 35, 63, -29, -419, -419, 35, 96, - -186, -188, -187, -189, 75, 79, 81, 76, 77, 78, - 82, -309, 28, -31, -168, -31, -419, -190, -183, -421, - 18, 86, -421, 96, 236, -271, -274, 437, 434, 440, - -387, 98, -111, 96, -360, -347, -238, -140, 46, -340, - 396, -333, 605, -333, -342, 98, -342, 105, 105, 105, - 97, -49, -44, -45, 36, 90, -367, -354, 98, 45, - -354, -354, -295, 97, -234, -139, -190, 85, -371, -371, - -371, 29, -2, 745, 751, 151, 95, 401, 22, -255, - 96, 97, -219, 315, 97, -113, -295, 97, 95, -352, - -352, -295, -419, 253, 34, 34, 689, 645, 637, -59, - -219, -218, -295, -334, 744, 743, 97, 255, 313, -144, - 454, -141, 98, 100, -190, -190, -190, -190, -190, -190, - 245, 242, 424, -410, 327, 98, -410, 298, 256, -183, - -190, 96, -84, 272, 267, -306, -306, 36, -190, 434, - 718, 716, -145, 156, 277, -162, -153, -119, -119, -150, - -316, 192, 361, 276, 359, 355, 375, 366, 394, 357, - 395, 352, 351, 350, -316, -314, -150, -210, -145, -145, - -145, 164, -145, 162, -145, -95, -94, -420, -420, -420, - -420, -420, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -230, -145, -145, -145, -420, 192, 361, -95, - -145, 18, -145, -314, -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, - -145, -210, -145, -210, -145, -145, -145, -145, -145, -385, - -385, -385, -385, -385, -210, -210, -210, -210, -145, -419, - -295, -98, -97, -96, 672, 257, -94, -164, -98, -164, - 235, -145, 235, 235, 235, -145, -211, -297, -145, -145, - -145, -145, -145, -145, -145, -145, -145, -145, -194, -348, - 295, -348, 295, -348, -265, 96, -276, 26, 18, 63, - 63, -167, -198, -132, -168, -295, -244, 699, -250, 52, - -248, -249, 53, -245, 54, 62, -335, -335, 183, -235, - -145, -266, 85, -267, -275, -218, -213, -215, -214, -419, - -254, -420, -295, -265, -267, -170, -171, -171, -170, -171, - 75, 75, 75, 80, 75, 80, 75, -187, -301, -420, - -145, -304, 86, -168, -168, -192, -301, 183, 434, 438, - 439, -360, -408, 130, 157, 34, 85, 392, 110, -406, - 191, 634, 684, 689, 645, 638, 679, -407, 259, 150, - 151, 271, 28, 47, 97, 96, 97, 96, 97, 97, - 96, -288, -287, -45, -44, -354, -354, 105, -387, 98, - 98, 255, -190, 85, 85, 85, -114, 749, 105, 95, - -3, 90, -145, 95, 23, -343, -218, -378, -328, -379, - -329, -330, -5, -6, -355, -117, 63, 110, -63, 50, - 254, 729, 730, 139, -419, 742, -370, -255, -374, -376, - -190, -149, -419, -161, -147, -146, -148, -154, 181, 182, - 276, 357, 358, -219, -190, -138, 304, 312, 95, -142, - 101, -389, 86, 295, 392, 295, 392, 98, -412, 328, - 98, -412, -190, -84, -49, -190, -283, -283, 36, -387, - -420, -162, -153, -126, 176, 597, -319, 604, -331, -331, - -331, -338, -331, 347, -331, 347, -331, -420, -420, -420, - 96, -420, 26, -420, 96, -145, 96, -95, -95, -95, - -95, -95, -122, 493, 96, 96, -420, 95, 95, -420, - -145, -420, -420, -420, 96, -420, -420, -420, -420, -420, - -420, -420, -420, -420, -420, -420, -420, -420, 96, -420, - 96, -420, 96, -420, 96, -420, 96, -420, 96, -420, - 96, -420, 96, -420, 96, -420, 96, -420, 96, -420, - 96, -420, 96, -420, 96, -420, 96, -420, 96, -420, - -420, 96, -420, -420, -420, 96, -420, 96, -420, 96, - -420, -420, -420, 96, -317, 690, -420, -420, -420, -420, - -420, -420, -420, -420, -420, -420, -420, -93, -296, -94, - 654, 654, -420, -94, -227, 96, -150, -420, -150, -150, - -150, -420, -420, -420, 96, -420, 96, 96, -420, 96, - -420, 96, -420, -420, -420, -420, 96, -195, 26, -419, - -195, -419, -195, -420, -261, -190, -198, -228, 20, -241, - 57, 367, -252, -251, 61, 53, -249, 23, 55, 23, - 33, -266, 96, 165, -308, 96, 28, -420, -420, 96, - 63, 236, -420, -198, -181, -180, 85, 86, -182, 85, - -180, 75, 75, -256, 96, -264, -168, -198, -198, 236, - 130, -419, -149, 16, 98, 98, -387, -405, 733, 734, - 34, 105, -354, -354, 151, 151, -190, 95, -333, 98, - -333, 105, 105, 34, 91, 92, 93, 34, 87, 88, - 89, -190, -190, -190, -190, -375, 95, 23, -145, 95, - 165, 97, -255, -255, 291, 176, -354, 727, 297, 297, - -354, -354, -354, -116, -115, 749, 97, -420, 96, -341, - 597, 600, -145, -155, -155, -256, 97, -383, 597, -388, - -295, -295, -295, -295, 105, 107, -420, 595, 82, 598, - -420, -333, -145, -145, -145, -145, -235, 98, -145, -145, - 105, 105, -95, -420, -145, -145, -145, -145, -145, -145, - -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -145, -145, -145, -145, -210, -145, -420, -178, -177, -179, - 710, 130, 34, -316, -420, -212, 289, -101, -100, -99, - 18, -420, -145, -119, -119, -119, -119, -145, -145, -145, - -145, -145, -145, -419, 75, 22, 20, -258, -295, 259, - -419, -258, -419, -304, -228, -229, 21, 23, -242, 59, - -240, 58, -240, -251, 23, 23, 98, 23, 98, 151, - -275, -145, -215, -303, 63, -29, -295, -213, -295, -230, - -145, 95, -145, -158, -198, -198, -145, -205, 517, 519, - 520, 521, 518, 523, 524, 525, 526, 527, 528, 529, - 530, 531, 532, 522, 533, 494, 495, 496, 117, 119, - 118, 127, 128, 497, 498, 499, 361, 545, 546, 540, - 543, 544, 542, 541, 376, 377, 500, 563, 564, 568, - 567, 565, 566, 569, 572, 573, 574, 575, 576, 577, - 579, 578, 570, 571, 548, 547, 549, 550, 551, 552, - 553, 554, 556, 555, 557, 558, 559, 560, 561, 562, - 580, 581, 582, 583, 584, 586, 585, 590, 589, 587, - 588, 592, 591, 501, 502, 120, 121, 122, 123, 124, - 125, 126, 503, 506, 504, 507, 508, 509, 514, 515, - 510, 511, 512, 513, 516, 387, 385, 386, 382, 381, - 380, 441, 446, 447, 449, 534, 535, 536, 537, 538, - 539, 691, 692, 693, 694, 695, 696, 697, 698, 98, - 98, 95, -145, 97, 97, -256, -374, -60, 97, -257, - -255, 105, 97, 292, -214, -419, 98, -354, -354, -354, - 105, 105, -303, -420, 96, -295, -407, -376, 601, 601, - -420, 28, -382, -381, -297, 95, 86, 68, 596, 599, - -420, -420, -420, 96, -420, -420, -420, 97, 97, -420, - -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, - -420, -420, -420, -420, -420, -420, -420, -420, -420, -420, - -420, 96, -420, -177, -179, -420, 85, -158, -230, 23, - -98, 314, 316, -98, -420, -420, -420, -420, -420, 96, - -420, -420, 96, -420, 96, -420, -420, -258, -420, 23, - 23, 96, -420, -258, -420, -258, -197, -229, -108, -107, - -106, 628, -145, -210, -243, 60, 85, 134, 98, 98, - 98, 16, -419, -213, 236, -308, -235, -255, -175, 401, - -230, -420, -255, 97, 28, 97, 751, 151, 97, -214, - -125, -419, 288, -303, 98, 98, -115, -118, -29, 96, - 165, -255, -190, 68, -145, -210, -420, 85, 609, 710, - -92, -91, -88, 721, 747, -210, -94, -94, -145, -145, - -145, -420, -295, 259, -420, -420, -108, 96, -105, -104, - -295, -320, 597, 85, 134, -267, -255, -308, -295, 97, - -420, -419, -235, 97, -239, -29, 95, -3, 288, -328, - -379, -329, -330, -5, -6, -355, -82, 597, -381, -359, - -301, -297, 98, 105, 97, 597, -420, -420, -90, 159, - 719, 687, -155, 235, -420, 96, -420, 96, -420, 96, - -106, 96, 28, 602, -420, -304, -176, -174, -295, 651, - -398, -397, 593, -408, -404, 130, 157, 110, -406, 689, - 645, 140, 141, -82, -145, 95, -420, -83, 303, 706, - 236, -389, 598, -90, 720, 665, 640, 665, 640, -150, - -145, -145, -145, -104, -419, -420, 96, 26, -321, -62, - 662, -395, -396, 85, -399, 407, 661, 682, 130, 98, - 97, -255, 264, -302, -383, 599, 156, -119, -420, 96, - -420, 96, -420, -93, -174, 658, -334, -158, -396, 85, - -395, 85, 17, 16, -4, 750, 97, 305, -90, 665, - 640, -145, -145, -420, -61, 29, -175, -394, 272, 267, - 270, 35, -394, 105, -4, -420, -420, 662, 266, 34, - 130, -158, -178, -177, -177, + 531, 532, 522, 533, 494, 495, 496, 117, 119, 118, + 127, 128, 497, 498, 499, 361, 545, 546, 540, 543, + 544, 542, 541, 376, 377, 500, 563, 564, 568, 567, + 565, 566, 569, 572, 573, 574, 575, 576, 577, 579, + 578, 570, 571, 548, 547, 549, 550, 551, 552, 553, + 554, 556, 555, 557, 558, 559, 560, 561, 562, 580, + 581, 582, 583, 584, 586, 585, 590, 589, 587, 588, + 592, 591, 501, 502, 120, 121, 122, 123, 124, 125, + 126, 503, 506, 504, 507, 508, 509, 514, 515, 510, + 511, 512, 513, 516, 387, 385, 386, 382, 381, 380, + 441, 446, 447, 449, 534, 535, 536, 537, 538, 539, + 695, 696, 697, 698, 699, 700, 701, 702, 98, 98, + 95, -146, 97, 97, -261, -379, -61, 97, -262, -260, + 105, 97, 292, -216, -424, 98, -359, -359, -359, 105, + 105, -308, -425, 96, -300, -412, -381, 601, 601, -425, + 28, -387, -386, -302, 95, 86, 68, 596, 599, -425, + -425, -425, 96, -425, -425, -425, 97, 97, -425, -425, + -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, + -425, -425, -425, -425, -425, -425, -425, -425, -425, -425, + 96, -425, -178, -180, -425, 85, -159, -235, 23, -99, + 314, 316, -99, -425, -425, -425, -425, -425, 96, -425, + -425, 96, -425, 96, -425, -425, -263, -425, 23, 23, + 96, -425, -263, -425, -263, -198, -234, -109, -108, -107, + 628, -146, -211, -248, 60, 85, 134, 98, 98, 98, + 16, -424, -215, 236, -313, -240, -260, -176, 401, -235, + -425, -260, 97, 28, 97, 755, 151, 97, -216, -126, + -424, 288, -308, 98, 98, -116, -119, -29, 96, 165, + -260, -191, 68, -146, -211, -425, 85, 609, 714, -93, + -92, -89, 725, 751, -211, -95, -95, -146, -146, -146, + -425, -300, 259, -425, -425, -109, 96, -106, -105, -300, + -325, 597, 85, 134, -272, -260, -313, -300, 97, -425, + -424, -240, 97, -244, -29, 95, -3, 288, -333, -384, + -334, -335, -5, -6, -360, -83, 597, -386, -364, -306, + -302, 98, 105, 97, 597, -425, -425, -91, 159, 723, + 687, -156, 235, -425, 96, -425, 96, -425, 96, -107, + 96, 28, 602, -425, -309, -177, -175, -300, 651, -403, + -402, 593, -413, -409, 130, 157, 110, -411, 689, 645, + 140, 141, -83, -146, 95, -425, -84, 303, 710, 236, + -394, 598, -91, 724, 665, 640, 665, 640, -151, -146, + -146, -146, -105, -424, -425, 96, 26, -326, -63, 662, + -400, -401, 85, -404, 407, 661, 682, 130, 98, 97, + -260, 264, -307, -388, 599, 156, -120, -425, 96, -425, + 96, -425, -94, -175, 658, -339, -159, -401, 85, -400, + 85, 17, 16, -4, 754, 97, 305, -91, 665, 640, + -146, -146, -425, -62, 29, -176, -399, 272, 267, 270, + 35, -399, 105, -4, -425, -425, 662, 266, 34, 130, + -159, -179, -178, -178, } var yyDef = [...]int{ - 889, -2, -2, 891, 2, 4, 5, 6, 7, 8, + 892, -2, -2, 894, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 70, 72, 73, 889, 889, 889, 0, 889, 0, - 0, 889, -2, -2, 889, 1644, 0, 889, 0, 884, - 0, -2, 804, 810, 0, 819, -2, 0, 0, 889, - 889, 2285, 2285, 884, 0, 0, 0, 0, 0, 889, - 889, 889, 889, 1649, 1502, 50, 889, 0, 85, 86, - 839, 840, 841, 65, 0, 2283, 890, 1, 3, 71, - 75, 0, 0, 0, 58, 1511, 0, 78, 0, 0, - 893, 0, 0, 1627, 889, 889, 0, 126, 127, 0, - 0, 0, -2, 130, -2, 159, 160, 161, 0, 166, - 609, 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, 1629, 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, 1529, 165, 1645, 1642, 1643, 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, 2257, 2258, - 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, - 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, - 2279, 2280, 2281, 2282, 0, 1621, 0, 722, 993, 0, - 885, 886, 0, 793, 793, 0, 793, 793, 793, 793, - 0, 0, 0, 736, 0, 0, 0, 0, 790, 0, - 752, 753, 0, 790, 0, 759, 796, 0, 0, 766, - 793, 793, 769, 2286, 0, 2286, 2286, 0, 0, 1612, - 0, 787, 785, 799, 800, 42, 803, 806, 807, 808, - 809, 812, 0, 823, 826, 1638, 1639, 0, 828, 833, - 852, 853, 0, 45, 1153, 0, 1017, 0, 1028, -2, - 1039, 1056, 1057, 1058, 1059, 1060, 1062, 1063, 1064, 0, - 0, 0, 0, 1069, 1070, 0, 0, 0, 0, 0, - 1133, 0, 0, 0, 0, 2008, 1473, 0, 0, 1435, - 1435, 1169, 1435, 1435, 1437, 1437, 1437, 1858, 2000, 2009, - 2188, 1819, 1825, 1826, 1827, 2134, 2135, 2136, 2137, 2229, - 2230, 2234, 1922, 1814, 2201, 2202, 0, 2282, 1961, 1969, - 1970, 1946, 1955, 1994, 2096, 2213, 1837, 1989, 2059, 1919, - 1941, 1942, 2077, 2078, 1965, 1966, 1945, 2140, 2142, 2158, - 2159, 2144, 2146, 2155, 2161, 2166, 2145, 2157, 2162, 2175, - 2179, 2182, 2183, 2184, 2152, 2150, 2163, 2167, 2169, 2171, - 2177, 2180, 2153, 2151, 2164, 2168, 2170, 2172, 2178, 2181, - 2139, 2143, 2147, 2156, 2174, 2154, 2173, 2148, 2160, 2165, - 2176, 2149, 2141, 1959, 1962, 1949, 1950, 1952, 1954, 1960, - 1967, 1973, 1951, 1972, 1971, 0, 1947, 1948, 1953, 1964, - 1968, 1956, 1957, 1958, 1963, 1974, 2015, 2014, 2013, 2058, - 1985, 2057, 0, 0, 0, 0, 0, 1808, 1864, 1865, - 2185, 1357, 1358, 1359, 1360, 0, 0, 0, 0, 0, - 0, 0, 290, 291, 1486, 1487, 44, 1152, 1608, 1437, - 1437, 1437, 1437, 1437, 1437, 1091, 1092, 1093, 1094, 1095, - 1121, 1122, 1128, 1129, 2072, 2073, 2074, 2075, 1902, 2224, - 1911, 1912, 2054, 2055, 1924, 1925, 2256, 2257, -2, -2, - -2, 232, 233, 234, 235, 236, 237, 238, 239, 0, - 1863, 2199, 2200, 228, 0, 0, 295, 292, 293, 294, - 1135, 1136, 248, 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, 297, 298, 2285, 0, 862, 0, - 0, 0, 0, 0, 0, 1650, 1651, 1511, 0, 1503, - 1502, 63, 0, 889, -2, 0, 0, 0, 0, 47, - 0, 52, 950, 892, 77, 76, 1551, 1554, 0, 0, - 0, 59, 1512, 67, 69, 1513, 0, 894, 895, 0, - 926, 930, 0, 0, 0, 1628, 1627, 1627, 102, 0, - 0, 103, 123, 124, 125, 0, 0, 109, 110, 1614, - 1615, 43, 0, 0, 177, 178, 0, 1109, 428, 0, - 173, 0, 421, 360, 0, 1529, 0, 0, 0, 0, - 0, 1625, 0, 1622, 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, 670, 0, 402, 0, 573, 574, 464, - 0, 0, 0, 0, 0, 0, 0, 0, 1630, 1631, - 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, 1542, 0, 0, 0, -2, 0, 714, - 0, 0, 0, 1623, 1623, 0, 721, 0, 0, 0, - 726, 0, 0, 727, 0, 790, 790, 788, 789, 729, - 730, 731, 732, 793, 0, 0, 410, 411, 412, 790, - 793, 0, 793, 793, 793, 793, 790, 790, 790, 793, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2286, - 796, 793, 0, 760, 0, 761, 762, 763, 764, 767, - 768, 770, 2287, 2288, 1640, 1641, 1652, 1653, 1654, 1655, - 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, + 39, 70, 72, 73, 892, 892, 892, 0, 892, 0, + 0, 892, -2, -2, 892, 1653, 0, 892, 0, 887, + 0, -2, 807, 813, 0, 822, -2, 0, 0, 892, + 892, 2298, 2298, 887, 0, 0, 0, 0, 0, 892, + 892, 892, 892, 1658, 1505, 50, 892, 0, 88, 89, + 842, 843, 844, 65, 0, 2296, 85, 892, 893, 1, + 3, 71, 75, 0, 0, 0, 58, 1514, 0, 78, + 0, 0, 896, 0, 0, 1636, 892, 892, 0, 129, + 130, 0, 0, 0, -2, 133, -2, 162, 163, 164, + 0, 169, 612, 529, 581, 527, 566, -2, 515, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 532, 404, 404, 0, 0, -2, 515, 515, 515, + 1638, 0, 0, 0, 563, 466, 404, 404, 404, 0, + 404, 404, 404, 404, 0, 0, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 1532, 168, 1654, 1651, 1652, 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, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, + 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, + 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, + 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, + 0, 1630, 0, 725, 996, 0, 888, 889, 0, 796, + 796, 0, 796, 796, 796, 796, 0, 0, 0, 739, + 0, 0, 0, 0, 793, 0, 755, 756, 0, 793, + 0, 762, 799, 0, 0, 769, 796, 796, 772, 2299, + 0, 2299, 2299, 0, 0, 1621, 0, 790, 788, 802, + 803, 42, 806, 809, 810, 811, 812, 815, 0, 826, + 829, 1647, 1648, 0, 831, 836, 855, 856, 0, 45, + 1156, 0, 1020, 0, 1031, -2, 1042, 1059, 1060, 1061, + 1062, 1063, 1065, 1066, 1067, 0, 0, 0, 0, 1072, + 1073, 0, 0, 0, 0, 0, 1136, 0, 0, 0, + 0, 2018, 1476, 0, 0, 1438, 1438, 1172, 1438, 1438, + 1440, 1440, 1440, 1867, 2010, 2019, 2200, 1828, 1834, 1835, + 1836, 2146, 2147, 2148, 2149, 2242, 2243, 2247, 1931, 1823, + 2214, 2215, 0, 2295, 1970, 1978, 1979, 1955, 1964, 2003, + 2108, 2226, 1846, 1998, 2070, 1928, 1950, 1951, 2089, 2090, + 1974, 1975, 1954, 2152, 2154, 2170, 2171, 2156, 2158, 2167, + 2173, 2178, 2157, 2169, 2174, 2187, 2191, 2194, 2195, 2196, + 2164, 2162, 2175, 2179, 2181, 2183, 2189, 2192, 2165, 2163, + 2176, 2180, 2182, 2184, 2190, 2193, 2151, 2155, 2159, 2168, + 2186, 2166, 2185, 2160, 2172, 2177, 2188, 2161, 2153, 1968, + 1971, 1958, 1959, 1961, 1963, 1969, 1976, 1982, 1960, 1981, + 1980, 0, 1956, 1957, 1962, 1973, 1977, 1965, 1966, 1967, + 1972, 1983, 2025, 2024, 2023, 2069, 1994, 2068, 0, 0, + 0, 0, 0, 1817, 1873, 1874, 2197, 1360, 1361, 1362, + 1363, 0, 0, 0, 0, 0, 0, 0, 293, 294, + 1489, 1490, 44, 1155, 1617, 1440, 1440, 1440, 1440, 1440, + 1440, 1094, 1095, 1096, 1097, 1098, 1124, 1125, 1131, 1132, + 2084, 2085, 2086, 2087, 1911, 2237, 1920, 1921, 2065, 2066, + 1933, 1934, 2269, 2270, -2, -2, -2, 235, 236, 237, + 238, 239, 240, 241, 242, 0, 1872, 2212, 2213, 231, + 0, 1615, 1616, 298, 295, 296, 297, 1138, 1139, 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, 291, + 292, 0, 300, 301, 2298, 0, 865, 0, 0, 0, + 0, 0, 0, 1659, 1660, 1514, 0, 1506, 1505, 63, + 0, 892, -2, 0, 0, 0, 0, 47, 0, 52, + 953, 0, 895, 77, 76, 1554, 1557, 0, 0, 0, + 59, 1515, 67, 69, 1516, 0, 897, 898, 0, 929, + 933, 0, 0, 0, 1637, 1636, 1636, 105, 0, 0, + 106, 126, 127, 128, 0, 0, 112, 113, 1623, 1624, + 43, 0, 0, 180, 181, 0, 1112, 431, 0, 176, + 0, 424, 363, 0, 1532, 0, 0, 0, 0, 0, + 1634, 0, 1631, 157, 158, 165, 166, 167, 404, 404, + 404, 578, 0, 0, 168, 168, 536, 537, 538, 0, + 0, -2, 429, 0, 516, 0, 0, 418, 418, 422, + 420, 421, 0, 0, 0, 0, 0, 0, 0, 0, + 555, 0, 556, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 673, 0, 405, 0, 576, 577, 467, 0, + 0, 0, 0, 0, 0, 0, 0, 1639, 1640, 0, + 553, 554, 0, 0, 0, 404, 404, 0, 0, 0, + 0, 404, 404, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 156, 1545, 0, 0, 0, -2, 0, 717, 0, + 0, 0, 1632, 1632, 0, 724, 0, 0, 0, 729, + 0, 0, 730, 0, 793, 793, 791, 792, 732, 733, + 734, 735, 796, 0, 0, 413, 414, 415, 793, 796, + 0, 796, 796, 796, 796, 793, 793, 793, 796, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2299, 799, + 796, 0, 763, 0, 764, 765, 766, 767, 770, 771, + 773, 2300, 2301, 1649, 1650, 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, @@ -9611,288 +9589,290 @@ var yyDef = [...]int{ 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, - 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 2286, - 2286, 774, 778, 782, 780, 1613, 805, 811, 813, 814, - 0, 0, 824, 827, 846, 49, 1910, 832, 49, 834, - 835, 836, 837, 838, 864, 865, 870, 0, 0, 0, - 0, 876, 877, 878, 0, 0, 881, 882, 883, 0, - 0, 0, 0, 0, 1015, 0, 0, 1141, 1142, 1143, - 1144, 1145, 1146, 1147, 1148, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1040, 1041, 0, 0, 0, 1065, 1066, - 1067, 1068, 1071, 0, 1082, 0, 1084, 1482, -2, 0, - 0, 0, 1076, 1077, 0, 0, 0, 1633, 1633, 0, - 0, 0, 1474, 0, 0, 1167, 0, 1168, 1170, 1171, - 1172, 0, 1173, 1174, 899, 899, 899, 899, 899, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 899, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1633, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 1633, 0, - 0, 1633, 1633, 0, 0, 220, 221, 222, 223, 224, - 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 240, 241, 242, 243, - 244, 299, 245, 246, 247, 1152, 0, 0, 0, 46, - 854, 855, 0, 976, 1633, 0, 0, 905, 0, 1648, - 57, 66, 68, 1511, 61, 1511, 0, 909, 0, 0, - -2, -2, 910, 911, 915, 916, 917, 918, 919, 920, - 921, 922, 923, 54, 2284, 55, 0, 74, 0, 48, - 0, 0, 1552, 0, 1555, 0, 0, 0, 374, 1559, - 0, 0, 1504, 1505, 1508, 0, 927, 2006, 931, 0, - 933, 934, 0, 0, 100, 0, 992, 0, 0, 0, - 111, 0, 113, 114, 0, 0, 0, 385, 1616, 1617, - 1618, -2, 408, 0, 385, 369, 307, 308, 309, 360, - 311, 360, 360, 360, 360, 374, 374, 374, 374, 342, - 343, 344, 345, 346, 0, 360, 0, 328, 360, 360, - 360, 360, 350, 351, 352, 353, 354, 355, 356, 357, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 362, - 362, 362, 362, 362, 366, 366, 0, 1110, 0, 389, - 0, 1508, 0, 0, 1542, 1625, 1635, 0, 0, 0, - 0, 0, 132, 0, 0, 0, 576, 620, 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, 650, - 962, 0, 0, 0, 0, 0, 656, 657, 658, 0, - 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, - 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, 979, 980, 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, - 1533, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1623, 0, - 0, 0, 0, 908, 994, 1646, 1647, 723, 0, 0, - 794, 795, 0, 413, 414, 793, 793, 733, 775, 0, - 793, 737, 776, 738, 740, 739, 741, 754, 755, 793, - 744, 791, 792, 745, 746, 747, 748, 749, 750, 751, - 771, 756, 757, 758, 797, 0, 801, 802, 772, 773, - 0, 783, 0, 0, 0, 817, 818, 0, 825, 849, - 847, 848, 850, 842, 843, 844, 845, 0, 851, 0, - 0, 867, 96, 872, 873, 874, 875, 887, 880, 1154, - 1012, 1013, 1014, 0, 1016, 1022, 0, 1137, 1139, 1020, - 1021, 1024, 0, 0, 0, 1018, 1029, 1149, 1150, 1151, - 0, 0, 0, 0, 0, 1033, 1037, 1042, 1043, 1044, - 1045, 1046, 0, 1047, 0, 1050, 1051, 1052, 1053, 1054, - 1055, 1061, 1450, 1451, 1452, 1080, 300, 301, 0, 1081, - 0, 0, 0, 0, 0, 0, 0, 0, 1397, 1398, - 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, - 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1153, 0, - 1634, 0, 0, 0, 1480, 1477, 0, 0, 0, 1436, - 1438, 0, 0, 0, 900, 901, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1417, 1418, 1419, 1420, 1421, 1422, 1423, - 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, - 1434, 0, 0, 1453, 0, 0, 0, 0, 0, 0, - 0, 1473, 0, 1086, 1087, 1088, 0, 0, 0, 0, - 0, 0, 1215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 1361, 1362, - 1363, 1364, 41, 0, 0, 0, 0, 0, 0, 0, - 1484, 0, -2, -2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, - 0, 0, 0, 0, 1606, 0, 0, 857, 858, 860, - 0, 996, 0, 977, 0, 0, 863, 0, 904, 0, - 907, 60, 62, 913, 914, 0, 935, 924, 912, 56, - 51, 0, 0, 954, 1553, 1556, 1557, 374, 1579, 0, - 383, 383, 380, 1514, 1515, 0, 1507, 1509, 1510, 79, - 932, 928, 0, 1010, 0, 0, 991, 0, 938, 940, - 941, 942, 974, 0, 945, 946, 0, 0, 0, 0, - 0, 98, 993, 104, 0, 112, 0, 0, 117, 118, - 105, 106, 107, 108, 0, 609, -2, 460, 179, 181, - 182, 183, 174, -2, 372, 370, 371, 310, 374, 374, - 336, 337, 338, 339, 340, 341, 0, 348, 0, 329, - 330, 331, 332, 321, 0, 322, 323, 324, 364, 0, - 325, 326, 0, 327, 427, 0, 1516, 390, 391, 393, - 401, 0, 396, 397, 0, 401, 401, 0, 422, 423, - 0, 1508, 1533, 0, 0, 1636, 1635, 1635, 1635, 152, - 0, 167, 168, 169, 170, 171, 172, 645, 0, 0, - 621, 643, 644, 165, 0, 0, 175, 516, 515, 0, - 677, 0, 425, 0, 0, 419, 419, 404, 405, 557, - 0, 0, 652, 653, 654, 655, 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, 595, 598, - 600, 518, 604, 606, 0, 594, 597, 599, 601, 518, - 605, 607, 1530, 1531, 1532, 0, 0, 715, 0, 0, - 451, 94, 1624, 720, 724, 725, 790, 743, 777, 790, - 735, 742, 765, 779, 781, 815, 816, 821, 829, 830, - 831, 871, 0, 0, 0, 0, 879, 0, 0, 1023, - 1138, 1140, 1025, 1026, 1027, 1030, 0, 1034, 1038, 0, - 0, 0, 0, 0, 1085, 1083, 1484, 0, 0, 0, - 1134, 0, 0, 1157, 1158, 0, 0, 0, 0, 1478, - 0, 0, 1165, 0, 1439, 1115, 0, 0, 0, 0, - 0, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 1502, 1192, 0, 0, 0, 0, 0, 1197, 1198, - 1199, 1115, 0, 1202, 1203, 0, 1205, 0, 1206, 0, - 0, 0, 0, 1213, 1214, 1216, 0, 0, 1219, 1220, - 0, 1222, 0, 1224, 1225, 1226, 1227, 1228, 1229, 0, - 1231, 0, 1233, 1234, 1235, 0, 1237, 0, 1239, 1240, - 0, 1242, 0, 1244, 0, 1247, 0, 1250, 0, 1253, - 0, 1256, 0, 1259, 0, 1262, 0, 1265, 0, 1268, - 0, 1271, 0, 1274, 0, 1277, 0, 1280, 0, 1283, - 0, 1286, 0, 1289, 0, 1292, 1293, 1294, 0, 1296, - 0, 1298, 0, 1301, 1302, 0, 1304, 0, 1307, 0, - 1310, 0, 0, 1311, 0, 0, 0, 1315, 0, 0, - 0, 0, 1324, 1325, 1326, 1327, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1338, 1339, 1340, 1341, - 1342, 1343, 0, 1345, 0, 1116, 0, 0, 1116, 0, - 0, 0, 0, 0, 1155, 1633, 0, 1440, 1441, 1442, - 1443, 1444, 0, 0, 0, 0, 0, 0, 1384, 1385, - 1387, 0, 0, 1390, 0, 1392, 0, 1607, 856, 859, - 861, 948, 997, 998, 0, 0, 0, 0, 978, 1632, - 902, 903, 906, 956, 0, 1488, 0, 0, 935, 1010, - 0, 936, 0, 53, 951, 0, 1561, 1560, 1573, 1586, - 383, 383, 377, 378, 384, 379, 381, 382, 1506, 0, - 1511, 0, 1600, 0, 0, 1589, 0, 0, 0, 0, - 0, 0, 0, 0, 981, 0, 0, 984, 0, 0, - 0, 0, 975, 946, 0, 947, 0, -2, 0, 0, - 92, 93, 0, 0, 0, 115, 116, 0, 0, 122, - 386, 387, 156, 165, 462, 180, 435, 0, 0, 306, - 373, 333, 334, 335, 0, 358, 0, 0, 0, 0, - 456, 128, 1520, 1519, 401, 401, 392, 0, 395, 0, - 0, 0, 1637, 361, 424, 0, 146, 0, 0, 0, - 0, 1626, 615, 0, 0, 622, 0, 0, 0, 525, - 0, 536, 537, 0, 649, -2, 711, 389, 0, 403, - 406, 963, 0, 0, 538, 0, 541, 542, 455, 516, - 547, 548, 562, 549, 497, 498, 495, 0, 0, 1543, - 1544, 1549, 1547, 1548, 133, 583, 585, 589, 584, 588, - 0, 0, 0, 520, 0, 608, 520, 581, 0, 451, - 1516, 0, 719, 452, 453, 793, 793, 866, 97, 0, - 869, 0, 0, 0, 0, 1031, 1035, 1048, 1049, 1445, - 1471, 360, 360, 1458, 360, 366, 1461, 360, 1463, 360, - 1466, 360, 1469, 1470, 0, 0, 1078, 0, 0, 0, - 0, 1164, 1481, 0, 0, 1175, 1114, 1115, 1115, 1115, - 1115, 1115, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, - 1189, 1190, 1475, 0, 0, 0, 1196, 0, 0, 1200, + 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, + 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 2299, 2299, + 777, 781, 785, 783, 1622, 808, 814, 816, 817, 0, + 0, 827, 830, 849, 49, 1919, 835, 49, 837, 838, + 839, 840, 841, 867, 868, 873, 0, 0, 0, 0, + 879, 880, 881, 0, 0, 884, 885, 886, 0, 0, + 0, 0, 0, 1018, 0, 0, 1144, 1145, 1146, 1147, + 1148, 1149, 1150, 1151, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1043, 1044, 0, 0, 0, 1068, 1069, 1070, + 1071, 1074, 0, 1085, 0, 1087, 1485, -2, 0, 0, + 0, 1079, 1080, 0, 0, 0, 1642, 1642, 0, 0, + 0, 1477, 0, 0, 1170, 0, 1171, 1173, 1174, 1175, + 0, 1176, 1177, 902, 902, 902, 902, 902, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 902, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1395, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1109, - 1113, 0, 1117, 1118, 0, 0, 1347, 0, 0, 1365, - 0, 0, 0, 0, 0, 0, 0, 1485, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 999, 1006, - 0, 1006, 0, 1006, 0, 0, 0, 1619, 1620, 1489, - 1490, 1010, 1491, 925, 937, 955, 1579, 0, 1572, 0, - -2, 1581, 0, 0, 0, 1587, 375, 376, 929, 80, - 1011, 83, 0, 1600, 1609, 0, 1597, 1602, 1604, 0, - 0, 0, 1593, 0, 1010, 939, 970, 972, 0, 967, - 982, 983, 985, 0, 987, 0, 989, 990, 950, 944, - 0, 100, 0, 1010, 1010, 99, 0, 995, 119, 120, - 121, 461, 184, 189, 0, 0, 0, 194, 0, 196, - 0, 0, 0, 201, 202, 401, 401, 436, 0, 303, - 305, 0, 0, 187, 374, 0, 374, 0, 365, 367, - 0, 437, 457, 1517, 1518, 0, 0, 394, 398, 399, - 400, 0, 148, 0, 0, 0, 618, 0, 646, 0, - 0, 0, 0, 0, 0, 176, 517, 678, 679, 680, - 681, 682, 683, 684, 685, 686, 0, 401, 0, 0, - 0, 401, 401, 401, 0, 703, 388, 0, 0, 674, - 671, 539, 0, 218, 219, 226, 227, 229, 0, 0, - 0, 0, 0, 546, 950, 1534, 1535, 1536, 0, 1546, - 1550, 136, 0, 0, 0, 0, 591, 596, 602, 0, - 519, 603, 716, 717, 718, 95, 728, 734, 868, 888, - 1019, 1032, 1036, 0, 0, 0, 0, 1472, 1456, 374, - 1459, 1460, 1462, 1464, 1465, 1467, 1468, 1074, 1075, 1079, - 0, 1161, 0, 1163, 0, 1479, 0, 1176, 1177, 1178, - 1179, 1180, 1511, 0, 0, 0, 1195, 0, 0, 1115, - 0, 1208, 1207, 1209, 0, 1211, 1212, 1217, 1218, 1221, - 1223, 1230, 1232, 1236, 1238, 1241, 1243, 1245, 0, 1248, - 0, 1251, 0, 1254, 0, 1257, 0, 1260, 0, 1263, - 0, 1266, 0, 1269, 0, 1272, 0, 1275, 0, 1278, - 0, 1281, 0, 1284, 0, 1287, 0, 1290, 0, 1295, - 1297, 0, 1300, 1303, 1305, 0, 1308, 0, 1312, 0, - 1314, 1316, 1317, 0, 0, 0, 1328, 1329, 1330, 1331, - 1332, 1333, 1334, 1335, 1336, 1337, 1344, 0, 1107, 1346, - 1119, 1120, 1125, 1349, 0, 0, 0, 1352, 0, 0, - 0, 1356, 1156, 1367, 0, 1372, 0, 0, 1378, 0, - 1382, 0, 1388, 1389, 1391, 1393, 0, 0, 0, 0, - 0, 0, 0, 976, 957, 64, 1491, 1495, 0, 1566, - 1564, 1564, 1574, 1575, 0, 0, 1582, 0, 0, 0, - 0, 84, 0, 0, 1588, 0, 0, 1605, 0, 0, - 0, 0, 101, 1502, 964, 971, 0, 0, 965, 0, - 966, 986, 988, 943, 0, 1010, 1010, 90, 91, 0, - 190, 0, 192, 0, 195, 197, 198, 199, 205, 206, - 207, 200, 0, 0, 302, 304, 0, 0, 347, 359, - 349, 0, 0, 1521, 1522, 1523, 1524, 1525, 1526, 1527, - 1528, 950, 149, 150, 151, 610, 0, 620, 0, 952, - 0, 613, 0, 528, 0, 0, 0, 401, 401, 401, - 0, 0, 0, 0, 688, 0, 0, 651, 0, 659, - 0, 0, 0, 230, 231, 0, 1545, 582, 0, 134, - 135, 0, 0, 587, 521, 522, 1072, 0, 0, 0, - 1073, 1457, 0, 0, 0, 0, 0, 1476, 0, 0, - 0, 0, 1201, 1204, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1320, 0, 0, 0, - 640, 641, 0, 1396, 1112, 1502, 0, 1116, 1126, 1127, - 0, 1116, 1366, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1007, 0, 0, 0, 958, 959, - 0, 0, 0, 996, 1495, 1500, 0, 0, 1569, 0, - 1562, 1565, 1563, 1576, 0, 0, 1583, 0, 1585, 0, - 1610, 1611, 1603, 1598, 0, 1592, 1595, 1597, 1594, 1511, - 968, 0, 973, 0, 1502, 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, 0, 0, 203, - 204, 0, 0, 363, 368, 0, 0, 0, 611, 0, - 953, 623, 614, 0, 701, 0, 705, 0, 0, 0, - 708, 709, 710, 687, 0, 691, 429, 675, 672, 673, - 540, 0, 137, 138, 0, 0, 0, 1446, 0, 1449, - 1159, 1162, 1160, 0, 1191, 1193, 1194, 1454, 1455, 1210, - 1246, 1249, 1252, 1255, 1258, 1261, 1264, 1267, 1270, 1273, - 1276, 1279, 1282, 1285, 1288, 1291, 1299, 1306, 1309, 1313, - 1318, 0, 1321, 0, 0, 1322, 0, 642, 1103, 0, - 0, 1123, 1124, 0, 1351, 1353, 1354, 1355, 1368, 0, - 1373, 1374, 0, 1379, 0, 1383, 1394, 0, 1001, 1008, - 1009, 0, 1004, 0, 1005, 0, 949, 1500, 82, 1501, - 1498, 0, 1496, 1493, 1558, 0, 1567, 1568, 1577, 1578, - 1584, 0, 0, 1597, 0, 1591, 87, 0, 0, 0, - 1511, 191, 0, 210, 0, 619, 0, 622, 612, 699, - 700, 0, 712, 704, 706, 707, 689, -2, 1537, 0, - 0, 0, 590, 1447, 0, 0, 1323, 0, 638, 639, - 1111, 1104, 0, 1089, 1090, 1108, 1348, 1350, 0, 0, - 0, 1000, 960, 961, 1002, 1003, 81, 0, 1497, 1131, - 0, 1492, 0, 1570, 1571, 1601, 0, 1590, 1596, 969, - 976, 0, 88, 442, 435, 1537, 0, 0, 0, 692, - 693, 694, 695, 696, 697, 698, 579, 1539, 139, 140, - 0, 509, 510, 511, 133, 0, 1166, 1319, 1105, 0, - 0, 0, 0, 0, 1369, 0, 1375, 0, 1380, 0, - 1499, 0, 0, 1494, 1599, 624, 0, 626, 0, -2, - 430, 443, 0, 185, 211, 212, 0, 0, 215, 216, - 217, 208, 209, 129, 0, 0, 713, 0, 1540, 1541, - 0, 136, 0, 0, 1096, 1097, 1098, 1099, 1101, 0, - 0, 0, 0, 1132, 1109, 625, 0, 0, 385, 0, - 635, 431, 432, 0, 438, 439, 440, 441, 213, 214, - 647, 0, 0, 508, 586, 1448, 0, 0, 1370, 0, - 1376, 0, 1381, 0, 627, 628, 636, 0, 433, 0, - 434, 0, 0, 0, 616, 0, 647, 1538, 1106, 1100, - 1102, 0, 0, 1130, 0, 637, 633, 444, 446, 447, - 0, 0, 445, 648, 617, 1371, 1377, 0, 448, 449, - 450, 629, 630, 631, 632, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1642, 0, 0, + 1642, 1642, 0, 0, 223, 224, 225, 226, 227, 228, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 299, 243, 244, 245, 246, 247, + 302, 248, 249, 250, 1155, 0, 0, 892, 0, 46, + 857, 858, 0, 979, 1642, 0, 0, 908, 0, 1657, + 57, 66, 68, 1514, 61, 1514, 0, 912, 0, 0, + -2, -2, 913, 914, 918, 919, 920, 921, 922, 923, + 924, 925, 926, 54, 2297, 55, 0, 74, 0, 48, + 0, 0, 79, 80, 1605, 1609, 0, 1555, 0, 1558, + 0, 0, 0, 377, 1562, 0, 0, 1507, 1508, 1511, + 0, 930, 2016, 934, 0, 936, 937, 0, 0, 103, + 0, 995, 0, 0, 0, 114, 0, 116, 117, 0, + 0, 0, 388, 1625, 1626, 1627, -2, 411, 0, 388, + 372, 310, 311, 312, 363, 314, 363, 363, 363, 363, + 377, 377, 377, 377, 345, 346, 347, 348, 349, 0, + 363, 0, 331, 363, 363, 363, 363, 353, 354, 355, + 356, 357, 358, 359, 360, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 365, 365, 365, 365, 365, 369, + 369, 0, 1113, 0, 392, 0, 1511, 0, 0, 1545, + 1634, 1644, 0, 0, 0, 0, 0, 135, 0, 0, + 0, 579, 623, 530, 567, 580, 0, 533, 534, -2, + 0, 0, 515, 0, 517, 0, 412, 0, -2, 0, + 422, 0, 418, 422, 419, 422, 410, 423, 557, 558, + 559, 0, 561, 562, 653, 965, 0, 0, 0, 0, + 0, 659, 660, 661, 0, 663, 664, 665, 666, 667, + 668, 669, 670, 671, 672, 568, 569, 570, 571, 572, + 573, 574, 575, 0, 0, 0, 0, 517, 0, 564, + 0, 0, 468, 469, 470, 0, 0, 473, 474, 475, + 476, 0, 0, 479, 480, 481, 982, 983, 482, 483, + 508, 509, 510, 484, 485, 486, 487, 488, 489, 490, + 502, 503, 504, 505, 506, 507, 491, 492, 493, 494, + 495, 496, 499, 0, 150, 1536, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1632, 0, 0, 0, 0, 911, 997, + 1655, 1656, 726, 0, 0, 797, 798, 0, 416, 417, + 796, 796, 736, 778, 0, 796, 740, 779, 741, 743, + 742, 744, 757, 758, 796, 747, 794, 795, 748, 749, + 750, 751, 752, 753, 754, 774, 759, 760, 761, 800, + 0, 804, 805, 775, 776, 0, 786, 0, 0, 0, + 820, 821, 0, 828, 852, 850, 851, 853, 845, 846, + 847, 848, 0, 854, 0, 0, 870, 99, 875, 876, + 877, 878, 890, 883, 1157, 1015, 1016, 1017, 0, 1019, + 1025, 0, 1140, 1142, 1023, 1024, 1027, 0, 0, 0, + 1021, 1032, 1152, 1153, 1154, 0, 0, 0, 0, 0, + 1036, 1040, 1045, 1046, 1047, 1048, 1049, 0, 1050, 0, + 1053, 1054, 1055, 1056, 1057, 1058, 1064, 1453, 1454, 1455, + 1083, 303, 304, 0, 1084, 0, 0, 0, 0, 0, + 0, 0, 0, 1400, 1401, 1402, 1403, 1404, 1405, 1406, + 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, + 1417, 1418, 1419, 1156, 0, 1643, 0, 0, 0, 1483, + 1480, 0, 0, 0, 1439, 1441, 0, 0, 0, 903, + 904, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1420, 1421, + 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, + 1432, 1433, 1434, 1435, 1436, 1437, 0, 0, 1456, 0, + 0, 0, 0, 0, 0, 0, 1476, 0, 1089, 1090, + 1091, 0, 0, 0, 0, 0, 0, 1218, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, + 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1364, 1365, 1366, 1367, 41, 0, 0, + 0, 0, 0, 0, 0, 1487, 0, -2, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1389, 0, 0, 0, 0, 0, 0, 1613, + 0, 0, 860, 861, 863, 0, 999, 0, 980, 0, + 0, 866, 0, 907, 0, 910, 60, 62, 916, 917, + 0, 938, 927, 915, 56, 51, 0, 0, 957, 0, + 0, 1556, 1559, 1560, 377, 1582, 0, 386, 386, 383, + 1517, 1518, 0, 1510, 1512, 1513, 81, 935, 931, 0, + 1013, 0, 0, 994, 0, 941, 943, 944, 945, 977, + 0, 948, 949, 0, 0, 0, 0, 0, 101, 996, + 107, 0, 115, 0, 0, 120, 121, 108, 109, 110, + 111, 0, 612, -2, 463, 182, 184, 185, 186, 177, + -2, 375, 373, 374, 313, 377, 377, 339, 340, 341, + 342, 343, 344, 0, 351, 0, 332, 333, 334, 335, + 324, 0, 325, 326, 327, 367, 0, 328, 329, 0, + 330, 430, 0, 1519, 393, 394, 396, 404, 0, 399, + 400, 0, 404, 404, 0, 425, 426, 0, 1511, 1536, + 0, 0, 1645, 1644, 1644, 1644, 155, 0, 170, 171, + 172, 173, 174, 175, 648, 0, 0, 624, 646, 647, + 168, 0, 0, 178, 519, 518, 0, 680, 0, 428, + 0, 0, 422, 422, 407, 408, 560, 0, 0, 655, + 656, 657, 658, 0, 0, 0, 546, 457, 0, 547, + 548, 517, 519, 0, 0, 388, 471, 472, 477, 478, + 497, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 595, 596, 598, 601, 603, 521, 607, + 609, 0, 597, 600, 602, 604, 521, 608, 610, 1533, + 1534, 1535, 0, 0, 718, 0, 0, 454, 97, 1633, + 723, 727, 728, 793, 746, 780, 793, 738, 745, 768, + 782, 784, 818, 819, 824, 832, 833, 834, 874, 0, + 0, 0, 0, 882, 0, 0, 1026, 1141, 1143, 1028, + 1029, 1030, 1033, 0, 1037, 1041, 0, 0, 0, 0, + 0, 1088, 1086, 1487, 0, 0, 0, 1137, 0, 0, + 1160, 1161, 0, 0, 0, 0, 1481, 0, 0, 1168, + 0, 1442, 1118, 0, 0, 0, 0, 0, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1505, 1195, + 0, 0, 0, 0, 0, 1200, 1201, 1202, 1118, 0, + 1205, 1206, 0, 1208, 0, 1209, 0, 0, 0, 0, + 1216, 1217, 1219, 0, 0, 1222, 1223, 0, 1225, 0, + 1227, 1228, 1229, 1230, 1231, 1232, 0, 1234, 0, 1236, + 1237, 1238, 0, 1240, 0, 1242, 1243, 0, 1245, 0, + 1247, 0, 1250, 0, 1253, 0, 1256, 0, 1259, 0, + 1262, 0, 1265, 0, 1268, 0, 1271, 0, 1274, 0, + 1277, 0, 1280, 0, 1283, 0, 1286, 0, 1289, 0, + 1292, 0, 1295, 1296, 1297, 0, 1299, 0, 1301, 0, + 1304, 1305, 0, 1307, 0, 1310, 0, 1313, 0, 0, + 1314, 0, 0, 0, 1318, 0, 0, 0, 0, 1327, + 1328, 1329, 1330, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1341, 1342, 1343, 1344, 1345, 1346, 0, + 1348, 0, 1119, 0, 0, 1119, 0, 0, 0, 0, + 0, 1158, 1642, 0, 1443, 1444, 1445, 1446, 1447, 0, + 0, 0, 0, 0, 0, 1387, 1388, 1390, 0, 0, + 1393, 0, 1395, 0, 1614, 859, 862, 864, 951, 1000, + 1001, 0, 0, 0, 0, 981, 1641, 905, 906, 909, + 959, 0, 1491, 0, 0, 938, 1013, 0, 939, 0, + 53, 954, 0, 1606, 1610, 1564, 1563, 1576, 1589, 386, + 386, 380, 381, 387, 382, 384, 385, 1509, 0, 1514, + 0, 1603, 0, 892, 1592, 0, 0, 0, 0, 0, + 0, 0, 0, 984, 0, 0, 987, 0, 0, 0, + 0, 978, 949, 0, 950, 0, -2, 0, 0, 95, + 96, 0, 0, 0, 118, 119, 0, 0, 125, 389, + 390, 159, 168, 465, 183, 438, 0, 0, 309, 376, + 336, 337, 338, 0, 361, 0, 0, 0, 0, 459, + 131, 1523, 1522, 404, 404, 395, 0, 398, 0, 0, + 0, 1646, 364, 427, 0, 149, 0, 0, 0, 0, + 1635, 618, 0, 0, 625, 0, 0, 0, 528, 0, + 539, 540, 0, 652, -2, 714, 392, 0, 406, 409, + 966, 0, 0, 541, 0, 544, 545, 458, 519, 550, + 551, 565, 552, 500, 501, 498, 0, 0, 1546, 1547, + 1552, 1550, 1551, 136, 586, 588, 592, 587, 591, 0, + 0, 0, 523, 0, 611, 523, 584, 0, 454, 1519, + 0, 722, 455, 456, 796, 796, 869, 100, 0, 872, + 0, 0, 0, 0, 1034, 1038, 1051, 1052, 1448, 1474, + 363, 363, 1461, 363, 369, 1464, 363, 1466, 363, 1469, + 363, 1472, 1473, 0, 0, 1081, 0, 0, 0, 0, + 1167, 1484, 0, 0, 1178, 1117, 1118, 1118, 1118, 1118, + 1118, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1193, 1478, 0, 0, 0, 1199, 0, 0, 1203, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 147, 148, + 0, 0, 0, 0, 0, 0, 1398, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1112, 1116, + 0, 1120, 1121, 0, 0, 1350, 0, 0, 1368, 0, + 0, 0, 0, 0, 0, 0, 1488, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1002, 1009, 0, + 1009, 0, 1009, 0, 0, 0, 1628, 1629, 1492, 1493, + 1013, 1494, 928, 940, 958, 1582, 0, 1575, 0, -2, + 1584, 0, 0, 0, 1590, 378, 379, 932, 82, 1014, + 86, 0, 1603, 1618, 0, 1600, 1607, 1611, 0, 0, + 0, 1596, 0, 1013, 942, 973, 975, 0, 970, 985, + 986, 988, 0, 990, 0, 992, 993, 953, 947, 0, + 103, 0, 1013, 1013, 102, 0, 998, 122, 123, 124, + 464, 187, 192, 0, 0, 0, 197, 0, 199, 0, + 0, 0, 204, 205, 404, 404, 439, 0, 306, 308, + 0, 0, 190, 377, 0, 377, 0, 368, 370, 0, + 440, 460, 1520, 1521, 0, 0, 397, 401, 402, 403, + 0, 151, 0, 0, 0, 621, 0, 649, 0, 0, + 0, 0, 0, 0, 179, 520, 681, 682, 683, 684, + 685, 686, 687, 688, 689, 0, 404, 0, 0, 0, + 404, 404, 404, 0, 706, 391, 0, 0, 677, 674, + 542, 0, 221, 222, 229, 230, 232, 0, 0, 0, + 0, 0, 549, 953, 1537, 1538, 1539, 0, 1549, 1553, + 139, 0, 0, 0, 0, 594, 599, 605, 0, 522, + 606, 719, 720, 721, 98, 731, 737, 871, 891, 1022, + 1035, 1039, 0, 0, 0, 0, 1475, 1459, 377, 1462, + 1463, 1465, 1467, 1468, 1470, 1471, 1077, 1078, 1082, 0, + 1164, 0, 1166, 0, 1482, 0, 1179, 1180, 1181, 1182, + 1183, 1514, 0, 0, 0, 1198, 0, 0, 1118, 0, + 1211, 1210, 1212, 0, 1214, 1215, 1220, 1221, 1224, 1226, + 1233, 1235, 1239, 1241, 1244, 1246, 1248, 0, 1251, 0, + 1254, 0, 1257, 0, 1260, 0, 1263, 0, 1266, 0, + 1269, 0, 1272, 0, 1275, 0, 1278, 0, 1281, 0, + 1284, 0, 1287, 0, 1290, 0, 1293, 0, 1298, 1300, + 0, 1303, 1306, 1308, 0, 1311, 0, 1315, 0, 1317, + 1319, 1320, 0, 0, 0, 1331, 1332, 1333, 1334, 1335, + 1336, 1337, 1338, 1339, 1340, 1347, 0, 1110, 1349, 1122, + 1123, 1128, 1352, 0, 0, 0, 1355, 0, 0, 0, + 1359, 1159, 1370, 0, 1375, 0, 0, 1381, 0, 1385, + 0, 1391, 1392, 1394, 1396, 0, 0, 0, 0, 0, + 0, 0, 979, 960, 64, 1494, 1498, 0, 1569, 1567, + 1567, 1577, 1578, 0, 0, 1585, 0, 0, 0, 0, + 87, 0, 0, 1591, 0, 0, 1612, 0, 0, 0, + 0, 104, 1505, 967, 974, 0, 0, 968, 0, 969, + 989, 991, 946, 0, 1013, 1013, 93, 94, 0, 193, + 0, 195, 0, 198, 200, 201, 202, 208, 209, 210, + 203, 0, 0, 305, 307, 0, 0, 350, 362, 352, + 0, 0, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, + 953, 152, 153, 154, 613, 0, 623, 0, 955, 0, + 616, 0, 531, 0, 0, 0, 404, 404, 404, 0, + 0, 0, 0, 691, 0, 0, 654, 0, 662, 0, + 0, 0, 233, 234, 0, 1548, 585, 0, 137, 138, + 0, 0, 590, 524, 525, 1075, 0, 0, 0, 1076, + 1460, 0, 0, 0, 0, 0, 1479, 0, 0, 0, + 0, 1204, 1207, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1323, 0, 0, 0, 643, + 644, 0, 1399, 1115, 1505, 0, 1119, 1129, 1130, 0, + 1119, 1369, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1010, 0, 0, 0, 961, 962, 0, + 0, 0, 999, 1498, 1503, 0, 0, 1572, 0, 1565, + 1568, 1566, 1579, 0, 0, 1586, 0, 1588, 0, 1619, + 1620, 1608, 1601, 892, 1595, 1598, 1600, 1597, 1514, 971, + 0, 976, 0, 1505, 92, 0, 196, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 206, 207, + 0, 0, 366, 371, 0, 0, 0, 614, 0, 956, + 626, 617, 0, 704, 0, 708, 0, 0, 0, 711, + 712, 713, 690, 0, 694, 432, 678, 675, 676, 543, + 0, 140, 141, 0, 0, 0, 1449, 0, 1452, 1162, + 1165, 1163, 0, 1194, 1196, 1197, 1457, 1458, 1213, 1249, + 1252, 1255, 1258, 1261, 1264, 1267, 1270, 1273, 1276, 1279, + 1282, 1285, 1288, 1291, 1294, 1302, 1309, 1312, 1316, 1321, + 0, 1324, 0, 0, 1325, 0, 645, 1106, 0, 0, + 1126, 1127, 0, 1354, 1356, 1357, 1358, 1371, 0, 1376, + 1377, 0, 1382, 0, 1386, 1397, 0, 1004, 1011, 1012, + 0, 1007, 0, 1008, 0, 952, 1503, 84, 1504, 1501, + 0, 1499, 1496, 1561, 0, 1570, 1571, 1580, 1581, 1587, + 0, 0, 1600, 0, 1594, 90, 0, 0, 0, 1514, + 194, 0, 213, 0, 622, 0, 625, 615, 702, 703, + 0, 715, 707, 709, 710, 692, -2, 1540, 0, 0, + 0, 593, 1450, 0, 0, 1326, 0, 641, 642, 1114, + 1107, 0, 1092, 1093, 1111, 1351, 1353, 0, 0, 0, + 1003, 963, 964, 1005, 1006, 83, 0, 1500, 1134, 0, + 1495, 0, 1573, 1574, 1604, 0, 1593, 1599, 972, 979, + 0, 91, 445, 438, 1540, 0, 0, 0, 695, 696, + 697, 698, 699, 700, 701, 582, 1542, 142, 143, 0, + 512, 513, 514, 136, 0, 1169, 1322, 1108, 0, 0, + 0, 0, 0, 1372, 0, 1378, 0, 1383, 0, 1502, + 0, 0, 1497, 1602, 627, 0, 629, 0, -2, 433, + 446, 0, 188, 214, 215, 0, 0, 218, 219, 220, + 211, 212, 132, 0, 0, 716, 0, 1543, 1544, 0, + 139, 0, 0, 1099, 1100, 1101, 1102, 1104, 0, 0, + 0, 0, 1135, 1112, 628, 0, 0, 388, 0, 638, + 434, 435, 0, 441, 442, 443, 444, 216, 217, 650, + 0, 0, 511, 589, 1451, 0, 0, 1373, 0, 1379, + 0, 1384, 0, 630, 631, 639, 0, 436, 0, 437, + 0, 0, 0, 619, 0, 650, 1541, 1109, 1103, 1105, + 0, 0, 1133, 0, 640, 636, 447, 449, 450, 0, + 0, 448, 651, 620, 1374, 1380, 0, 451, 452, 453, + 632, 633, 634, 635, } var yyTok1 = [...]int{ @@ -9901,7 +9881,7 @@ var yyTok1 = [...]int{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 158, 3, 3, 3, 186, 178, 3, 95, 97, 183, 181, 96, 182, 236, 184, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 752, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 756, 166, 165, 167, 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, @@ -10036,7 +10016,8 @@ var yyTok3 = [...]int{ 58060, 735, 58061, 736, 58062, 737, 58063, 738, 58064, 739, 58065, 740, 58066, 741, 58067, 742, 58068, 743, 58069, 744, 58070, 745, 58071, 746, 58072, 747, 58073, 748, 58074, 749, - 58075, 750, 58076, 751, 0, + 58075, 750, 58076, 751, 58077, 752, 58078, 753, 58079, 754, + 58080, 755, 0, } var yyErrorMessages = [...]struct { @@ -10386,7 +10367,7 @@ yydefault: case 1: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:631 +//line sql.y:633 { stmt := yyDollar[2].statementUnion() // If the statement is empty and we have comments @@ -10400,46 +10381,46 @@ yydefault: } case 2: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:644 +//line sql.y:646 { } case 3: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:645 +//line sql.y:647 { } case 4: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:649 +//line sql.y:651 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 40: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:688 +//line sql.y:690 { setParseTree(yylex, nil) } case 41: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:694 +//line sql.y:696 { yyLOCAL = NewVariableExpression(yyDollar[1].str, SingleAt) } yyVAL.union = yyLOCAL case 42: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:700 +//line sql.y:702 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 43: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:706 +//line sql.y:708 { yyLOCAL = NewVariableExpression(string(yyDollar[1].str), SingleAt) } @@ -10447,7 +10428,7 @@ yydefault: case 44: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:710 +//line sql.y:712 { yyLOCAL = NewVariableExpression(string(yyDollar[1].str), DoubleAt) } @@ -10455,7 +10436,7 @@ yydefault: case 45: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:716 +//line sql.y:718 { yyLOCAL = &OtherAdmin{} } @@ -10463,7 +10444,7 @@ yydefault: case 46: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:722 +//line sql.y:724 { yyLOCAL = &Load{} } @@ -10471,7 +10452,7 @@ yydefault: case 47: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *With -//line sql.y:728 +//line sql.y:730 { yyLOCAL = &With{CTEs: yyDollar[2].ctesUnion(), Recursive: false} } @@ -10479,7 +10460,7 @@ yydefault: case 48: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *With -//line sql.y:732 +//line sql.y:734 { yyLOCAL = &With{CTEs: yyDollar[3].ctesUnion(), Recursive: true} } @@ -10487,7 +10468,7 @@ yydefault: case 49: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *With -//line sql.y:737 +//line sql.y:739 { yyLOCAL = nil } @@ -10495,14 +10476,14 @@ yydefault: case 50: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *With -//line sql.y:741 +//line sql.y:743 { yyLOCAL = yyDollar[1].withUnion() } yyVAL.union = yyLOCAL case 51: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:747 +//line sql.y:749 { yySLICE := (*[]*CommonTableExpr)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].cteUnion()) @@ -10510,7 +10491,7 @@ yydefault: case 52: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*CommonTableExpr -//line sql.y:751 +//line sql.y:753 { yyLOCAL = []*CommonTableExpr{yyDollar[1].cteUnion()} } @@ -10518,266 +10499,290 @@ yydefault: case 53: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *CommonTableExpr -//line sql.y:757 +//line sql.y:759 { yyLOCAL = &CommonTableExpr{ID: yyDollar[1].identifierCS, Columns: yyDollar[2].columnsUnion(), Subquery: yyDollar[4].subqueryUnion().Select} } yyVAL.union = yyLOCAL case 54: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:763 + var yyLOCAL TableStatement +//line sql.y:765 { - yyLOCAL = yyDollar[2].selStmtUnion() + yyLOCAL = yyDollar[2].tableStmtUnion() } yyVAL.union = yyLOCAL case 55: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:767 + var yyLOCAL TableStatement +//line sql.y:769 { - yyLOCAL = yyDollar[2].selStmtUnion() + yyLOCAL = yyDollar[2].tableStmtUnion() } yyVAL.union = yyLOCAL case 56: yyDollar = yyS[yypt-4 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:771 + var yyLOCAL TableStatement +//line sql.y:773 { - setLockInSelect(yyDollar[2].selStmtUnion(), yyDollar[3].lockUnion()) - yyLOCAL = yyDollar[2].selStmtUnion() + setLockIfPossible(yylex, yyDollar[2].tableStmtUnion(), yyDollar[3].lockUnion()) + yyLOCAL = yyDollar[2].tableStmtUnion() } yyVAL.union = yyLOCAL case 57: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:794 + var yyLOCAL TableStatement +//line sql.y:796 { - yyDollar[1].selStmtUnion().SetOrderBy(yyDollar[2].orderByUnion()) - yyDollar[1].selStmtUnion().SetLimit(yyDollar[3].limitUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + yyDollar[1].tableStmtUnion().SetOrderBy(yyDollar[2].orderByUnion()) + yyDollar[1].tableStmtUnion().SetLimit(yyDollar[3].limitUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 58: yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:800 + var yyLOCAL TableStatement +//line sql.y:802 { - yyDollar[1].selStmtUnion().SetLimit(yyDollar[2].limitUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + yyDollar[1].tableStmtUnion().SetLimit(yyDollar[2].limitUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 59: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:805 + var yyLOCAL TableStatement +//line sql.y:807 { - yyDollar[1].selStmtUnion().SetOrderBy(yyDollar[2].orderByUnion()) - yyDollar[1].selStmtUnion().SetLimit(yyDollar[3].limitUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + yyDollar[1].tableStmtUnion().SetOrderBy(yyDollar[2].orderByUnion()) + yyDollar[1].tableStmtUnion().SetLimit(yyDollar[3].limitUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 60: yyDollar = yyS[yypt-4 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:811 + var yyLOCAL TableStatement +//line sql.y:813 { - yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) - yyDollar[2].selStmtUnion().SetOrderBy(yyDollar[3].orderByUnion()) - yyDollar[2].selStmtUnion().SetLimit(yyDollar[4].limitUnion()) - yyLOCAL = yyDollar[2].selStmtUnion() + yyDollar[2].tableStmtUnion().SetWith(yyDollar[1].withUnion()) + yyDollar[2].tableStmtUnion().SetOrderBy(yyDollar[3].orderByUnion()) + yyDollar[2].tableStmtUnion().SetLimit(yyDollar[4].limitUnion()) + yyLOCAL = yyDollar[2].tableStmtUnion() } yyVAL.union = yyLOCAL case 61: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:818 + var yyLOCAL TableStatement +//line sql.y:820 { - yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) - yyDollar[2].selStmtUnion().SetLimit(yyDollar[3].limitUnion()) - yyLOCAL = yyDollar[2].selStmtUnion() + yyDollar[2].tableStmtUnion().SetWith(yyDollar[1].withUnion()) + yyDollar[2].tableStmtUnion().SetLimit(yyDollar[3].limitUnion()) + yyLOCAL = yyDollar[2].tableStmtUnion() } yyVAL.union = yyLOCAL case 62: yyDollar = yyS[yypt-4 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:824 + var yyLOCAL TableStatement +//line sql.y:826 { - yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) - yyDollar[2].selStmtUnion().SetOrderBy(yyDollar[3].orderByUnion()) - yyDollar[2].selStmtUnion().SetLimit(yyDollar[4].limitUnion()) - yyLOCAL = yyDollar[2].selStmtUnion() + yyDollar[2].tableStmtUnion().SetWith(yyDollar[1].withUnion()) + yyDollar[2].tableStmtUnion().SetOrderBy(yyDollar[3].orderByUnion()) + yyDollar[2].tableStmtUnion().SetLimit(yyDollar[4].limitUnion()) + yyLOCAL = yyDollar[2].tableStmtUnion() } yyVAL.union = yyLOCAL case 63: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:831 +//line sql.y:833 { - yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) + yyDollar[2].tableStmtUnion().SetWith(yyDollar[1].withUnion()) } case 64: yyDollar = yyS[yypt-7 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:835 + var yyLOCAL TableStatement +//line sql.y:837 { 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) } yyVAL.union = yyLOCAL case 65: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:841 + var yyLOCAL TableStatement +//line sql.y:843 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 66: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:845 + var yyLOCAL TableStatement +//line sql.y:847 { - yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} + yyLOCAL = &Union{Left: yyDollar[1].tableStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].tableStmtUnion()} } yyVAL.union = yyLOCAL case 67: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:849 + var yyLOCAL TableStatement +//line sql.y:851 { - yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} + yyLOCAL = &Union{Left: yyDollar[1].tableStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].tableStmtUnion()} } yyVAL.union = yyLOCAL case 68: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:853 + var yyLOCAL TableStatement +//line sql.y:855 { - yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} + yyLOCAL = &Union{Left: yyDollar[1].tableStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].tableStmtUnion()} } yyVAL.union = yyLOCAL case 69: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:857 + var yyLOCAL TableStatement +//line sql.y:859 { - yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} + yyLOCAL = &Union{Left: yyDollar[1].tableStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].tableStmtUnion()} } yyVAL.union = yyLOCAL case 70: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:863 + var yyLOCAL TableStatement +//line sql.y:865 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 71: yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:867 + var yyLOCAL TableStatement +//line sql.y:869 { - setLockInSelect(yyDollar[1].selStmtUnion(), yyDollar[2].lockUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + setLockIfPossible(yylex, yyDollar[1].tableStmtUnion(), yyDollar[2].lockUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 72: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:872 + var yyLOCAL TableStatement +//line sql.y:874 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 73: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:876 + var yyLOCAL TableStatement +//line sql.y:878 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 74: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:882 + var yyLOCAL TableStatement +//line sql.y:884 { - yyLOCAL = yyDollar[2].selStmtUnion() + yyLOCAL = yyDollar[2].tableStmtUnion() } yyVAL.union = yyLOCAL case 75: yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:886 + var yyLOCAL TableStatement +//line sql.y:888 { - yyDollar[1].selStmtUnion().SetInto(yyDollar[2].selectIntoUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + setIntoIfPossible(yylex, yyDollar[1].tableStmtUnion(), yyDollar[2].selectIntoUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 76: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:891 + var yyLOCAL TableStatement +//line sql.y:893 { - yyDollar[1].selStmtUnion().SetInto(yyDollar[2].selectIntoUnion()) - yyDollar[1].selStmtUnion().SetLock(yyDollar[3].lockUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + setIntoIfPossible(yylex, yyDollar[1].tableStmtUnion(), yyDollar[2].selectIntoUnion()) + setLockIfPossible(yylex, yyDollar[1].tableStmtUnion(), yyDollar[3].lockUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 77: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:897 + var yyLOCAL TableStatement +//line sql.y:899 { - yyDollar[1].selStmtUnion().SetInto(yyDollar[3].selectIntoUnion()) - yyDollar[1].selStmtUnion().SetLock(yyDollar[2].lockUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + setLockIfPossible(yylex, yyDollar[1].tableStmtUnion(), yyDollar[2].lockUnion()) + setIntoIfPossible(yylex, yyDollar[1].tableStmtUnion(), yyDollar[3].selectIntoUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 78: yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:903 + var yyLOCAL TableStatement +//line sql.y:905 { - yyDollar[1].selStmtUnion().SetInto(yyDollar[2].selectIntoUnion()) - yyLOCAL = yyDollar[1].selStmtUnion() + setIntoIfPossible(yylex, yyDollar[1].tableStmtUnion(), yyDollar[2].selectIntoUnion()) + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL case 79: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL TableStatement +//line sql.y:912 + { + yyLOCAL = &ValuesStatement{Comments: Comments(yyDollar[2].strs).Parsed(), ListArg: ListArg(yyDollar[3].str[2:])} + } + yyVAL.union = yyLOCAL + case 80: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL TableStatement +//line sql.y:916 + { + yyLOCAL = &ValuesStatement{Comments: Comments(yyDollar[2].strs).Parsed(), Rows: yyDollar[3].valuesUnion()} + } + yyVAL.union = yyLOCAL + case 81: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:910 +//line sql.y:922 { yyLOCAL = &Stream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: yyDollar[3].selectExprUnion(), Table: yyDollar[5].tableName} } yyVAL.union = yyLOCAL - case 80: + case 82: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:916 +//line sql.y:928 { 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()} } yyVAL.union = yyLOCAL - case 81: + case 83: yyDollar = yyS[yypt-10 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:924 + var yyLOCAL TableStatement +//line sql.y:936 { 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()) } yyVAL.union = yyLOCAL - case 82: + case 84: yyDollar = yyS[yypt-9 : yypt+1] - var yyLOCAL SelectStatement -//line sql.y:928 + var yyLOCAL TableStatement +//line sql.y:940 { 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()) } yyVAL.union = yyLOCAL - case 83: + case 85: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL TableStatement +//line sql.y:944 + { + yyLOCAL = yyDollar[1].tableStmtUnion() + } + yyVAL.union = yyLOCAL + case 86: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:934 +//line sql.y:950 { // insert_data returns a *Insert pre-filled with Columns & Values ins := yyDollar[6].insUnion() @@ -10790,10 +10795,10 @@ yydefault: yyLOCAL = ins } yyVAL.union = yyLOCAL - case 84: + case 87: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:946 +//line sql.y:962 { cols := make(Columns, 0, len(yyDollar[7].updateExprsUnion())) vals := make(ValTuple, 0, len(yyDollar[8].updateExprsUnion())) @@ -10804,329 +10809,329 @@ yydefault: yyLOCAL = &Insert{Action: yyDollar[1].insertActionUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), Ignore: yyDollar[3].ignoreUnion(), Table: getAliasedTableExprFromTableName(yyDollar[4].tableName), Partitions: yyDollar[5].partitionsUnion(), Columns: cols, Rows: Values{vals}, OnDup: OnDup(yyDollar[8].updateExprsUnion())} } yyVAL.union = yyLOCAL - case 85: + case 88: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL InsertAction -//line sql.y:958 +//line sql.y:974 { yyLOCAL = InsertAct } yyVAL.union = yyLOCAL - case 86: + case 89: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL InsertAction -//line sql.y:962 +//line sql.y:978 { yyLOCAL = ReplaceAct } yyVAL.union = yyLOCAL - case 87: + case 90: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Statement -//line sql.y:968 +//line sql.y:984 { 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()} } yyVAL.union = yyLOCAL - case 88: + case 91: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL Statement -//line sql.y:974 +//line sql.y:990 { 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()} } yyVAL.union = yyLOCAL - case 89: + case 92: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Statement -//line sql.y:978 +//line sql.y:994 { 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())} } yyVAL.union = yyLOCAL - case 90: + case 93: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:982 +//line sql.y:998 { 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 91: + case 94: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:986 +//line sql.y:1002 { 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: + case 95: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:991 +//line sql.y:1007 { } - case 93: + case 96: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:992 +//line sql.y:1008 { } - case 94: + case 97: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:996 +//line sql.y:1012 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL - case 95: + case 98: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1000 +//line sql.y:1016 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) } - case 96: + case 99: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:1006 +//line sql.y:1022 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL - case 97: + case 100: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1010 +//line sql.y:1026 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) } - case 98: + case 101: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:1016 +//line sql.y:1032 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL - case 99: + case 102: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1020 +//line sql.y:1036 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) } - case 100: + case 103: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Partitions -//line sql.y:1025 +//line sql.y:1041 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 101: + case 104: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Partitions -//line sql.y:1029 +//line sql.y:1045 { yyLOCAL = yyDollar[3].partitionsUnion() } yyVAL.union = yyLOCAL - case 102: + case 105: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:1035 +//line sql.y:1051 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), yyDollar[3].setExprsUnion()) } yyVAL.union = yyLOCAL - case 103: + case 106: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:1041 +//line sql.y:1057 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL - case 104: + case 107: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1045 +//line sql.y:1061 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) } - case 105: + case 108: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1051 +//line sql.y:1067 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: NewStrLiteral("on")} } yyVAL.union = yyLOCAL - case 106: + case 109: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1055 +//line sql.y:1071 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: NewStrLiteral("off")} } yyVAL.union = yyLOCAL - case 107: + case 110: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1059 +//line sql.y:1075 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 108: + case 111: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1063 +//line sql.y:1079 { yyLOCAL = &SetExpr{Var: NewSetVariable(string(yyDollar[1].str), SessionScope), Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 109: + case 112: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:1069 +//line sql.y:1085 { yyLOCAL = NewSetVariable(string(yyDollar[1].str), SessionScope) } yyVAL.union = yyLOCAL - case 110: + case 113: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:1073 +//line sql.y:1089 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 111: + case 114: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Variable -//line sql.y:1077 +//line sql.y:1093 { yyLOCAL = NewSetVariable(string(yyDollar[2].str), yyDollar[1].scopeUnion()) } yyVAL.union = yyLOCAL - case 112: + case 115: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:1083 +//line sql.y:1099 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), UpdateSetExprsScope(yyDollar[5].setExprsUnion(), yyDollar[3].scopeUnion())) } yyVAL.union = yyLOCAL - case 113: + case 116: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:1087 +//line sql.y:1103 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), yyDollar[4].setExprsUnion()) } yyVAL.union = yyLOCAL - case 114: + case 117: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:1093 +//line sql.y:1109 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL - case 115: + case 118: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1097 +//line sql.y:1113 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) } - case 116: + case 119: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1103 +//line sql.y:1119 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionIsolationStr, NextTxScope), Expr: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 117: + case 120: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1107 +//line sql.y:1123 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionReadOnlyStr, NextTxScope), Expr: NewStrLiteral("off")} } yyVAL.union = yyLOCAL - case 118: + case 121: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1111 +//line sql.y:1127 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionReadOnlyStr, NextTxScope), Expr: NewStrLiteral("on")} } yyVAL.union = yyLOCAL - case 119: + case 122: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1117 +//line sql.y:1133 { yyVAL.str = RepeatableReadStr } - case 120: + case 123: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1121 +//line sql.y:1137 { yyVAL.str = ReadCommittedStr } - case 121: + case 124: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1125 +//line sql.y:1141 { yyVAL.str = ReadUncommittedStr } - case 122: + case 125: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1129 +//line sql.y:1145 { yyVAL.str = SerializableStr } - case 123: + case 126: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1135 +//line sql.y:1151 { yyLOCAL = SessionScope } yyVAL.union = yyLOCAL - case 124: + case 127: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1139 +//line sql.y:1155 { yyLOCAL = SessionScope } yyVAL.union = yyLOCAL - case 125: + case 128: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1143 +//line sql.y:1159 { yyLOCAL = GlobalScope } yyVAL.union = yyLOCAL - case 126: + case 129: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1149 +//line sql.y:1165 { yyDollar[1].createTableUnion().TableSpec = yyDollar[2].tableSpecUnion() yyDollar[1].createTableUnion().FullyParsed = true yyLOCAL = yyDollar[1].createTableUnion() } yyVAL.union = yyLOCAL - case 127: + case 130: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1155 +//line sql.y:1171 { // Create table [name] like [name] yyDollar[1].createTableUnion().OptLike = yyDollar[2].optLikeUnion() @@ -11134,10 +11139,10 @@ yydefault: yyLOCAL = yyDollar[1].createTableUnion() } yyVAL.union = yyLOCAL - case 128: + case 131: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:1162 +//line sql.y:1178 { indexDef := yyDollar[1].alterTableUnion().AlterOptions[0].(*AddIndexDefinition).IndexDefinition indexDef.Columns = yyDollar[3].indexColumnsUnion() @@ -11147,413 +11152,413 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 129: + case 132: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Statement -//line sql.y:1171 +//line sql.y:1187 { - 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} + 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].tableStmtUnion(), CheckOption: yyDollar[12].str} } yyVAL.union = yyLOCAL - case 130: + case 133: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1175 +//line sql.y:1191 { yyDollar[1].createDatabaseUnion().FullyParsed = true yyDollar[1].createDatabaseUnion().CreateOptions = yyDollar[2].databaseOptionsUnion() yyLOCAL = yyDollar[1].createDatabaseUnion() } yyVAL.union = yyLOCAL - case 131: + case 134: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:1182 +//line sql.y:1198 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 132: + case 135: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:1186 +//line sql.y:1202 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 133: + case 136: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1191 +//line sql.y:1207 { yyVAL.identifierCI = NewIdentifierCI("") } - case 134: + case 137: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1195 +//line sql.y:1211 { yyVAL.identifierCI = yyDollar[2].identifierCI } - case 135: + case 138: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1201 +//line sql.y:1217 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 136: + case 139: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1206 +//line sql.y:1222 { var v []VindexParam yyLOCAL = v } yyVAL.union = yyLOCAL - case 137: + case 140: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1211 +//line sql.y:1227 { yyLOCAL = yyDollar[2].vindexParamsUnion() } yyVAL.union = yyLOCAL - case 138: + case 141: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1217 +//line sql.y:1233 { yyLOCAL = make([]VindexParam, 0, 4) yyLOCAL = append(yyLOCAL, yyDollar[1].vindexParam) } yyVAL.union = yyLOCAL - case 139: + case 142: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1222 +//line sql.y:1238 { yySLICE := (*[]VindexParam)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].vindexParam) } - case 140: + case 143: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1228 +//line sql.y:1244 { yyVAL.vindexParam = VindexParam{Key: yyDollar[1].identifierCI, Val: yyDollar[3].str} } - case 141: + case 144: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1233 +//line sql.y:1249 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 142: + case 145: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1237 +//line sql.y:1253 { yyLOCAL = yyDollar[1].jsonObjectParamsUnion() } yyVAL.union = yyLOCAL - case 143: + case 146: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1243 +//line sql.y:1259 { yyLOCAL = []*JSONObjectParam{yyDollar[1].jsonObjectParam} } yyVAL.union = yyLOCAL - case 144: + case 147: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1247 +//line sql.y:1263 { yySLICE := (*[]*JSONObjectParam)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].jsonObjectParam) } - case 145: + case 148: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1253 +//line sql.y:1269 { yyVAL.jsonObjectParam = &JSONObjectParam{Key: yyDollar[1].exprUnion(), Value: yyDollar[3].exprUnion()} } - case 146: + case 149: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *CreateTable -//line sql.y:1259 +//line sql.y:1275 { yyLOCAL = &CreateTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[6].tableName, IfNotExists: yyDollar[5].booleanUnion(), Temp: yyDollar[3].booleanUnion()} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 147: + case 150: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1266 +//line sql.y:1282 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[4].tableName} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 148: + case 151: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1273 +//line sql.y:1289 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[7].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[4].identifierCI}, Options: yyDollar[5].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 149: + case 152: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1278 +//line sql.y:1294 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeFullText}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 150: + case 153: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1283 +//line sql.y:1299 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeSpatial}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 151: + case 154: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1288 +//line sql.y:1304 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeUnique}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 152: + case 155: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *CreateDatabase -//line sql.y:1295 +//line sql.y:1311 { yyLOCAL = &CreateDatabase{Comments: Comments(yyDollar[2].strs).Parsed(), DBName: yyDollar[5].identifierCS, IfNotExists: yyDollar[4].booleanUnion()} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 153: + case 156: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AlterDatabase -//line sql.y:1302 +//line sql.y:1318 { yyLOCAL = &AlterDatabase{Comments: Comments(yyDollar[2].strs).Parsed()} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 156: + case 159: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1313 +//line sql.y:1329 { yyLOCAL = yyDollar[2].tableSpecUnion() yyLOCAL.Options = yyDollar[4].tableOptionsUnion() yyLOCAL.PartitionOption = yyDollar[5].partitionOptionUnion() } yyVAL.union = yyLOCAL - case 157: + case 160: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1320 +//line sql.y:1336 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 158: + case 161: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1324 +//line sql.y:1340 { yyLOCAL = yyDollar[1].databaseOptionsUnion() } yyVAL.union = yyLOCAL - case 159: + case 162: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1330 +//line sql.y:1346 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } yyVAL.union = yyLOCAL - case 160: + case 163: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1334 +//line sql.y:1350 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } yyVAL.union = yyLOCAL - case 161: + case 164: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1338 +//line sql.y:1354 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } yyVAL.union = yyLOCAL - case 162: + case 165: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1342 +//line sql.y:1358 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } - case 163: + case 166: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1346 +//line sql.y:1362 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } - case 164: + case 167: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1350 +//line sql.y:1366 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } - case 165: + case 168: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:1356 +//line sql.y:1372 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 166: + case 169: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:1360 +//line sql.y:1376 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 167: + case 170: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1366 +//line sql.y:1382 { yyVAL.databaseOption = DatabaseOption{Type: CharacterSetType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 168: + case 171: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1370 +//line sql.y:1386 { yyVAL.databaseOption = DatabaseOption{Type: CharacterSetType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 169: + case 172: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1376 +//line sql.y:1392 { yyVAL.databaseOption = DatabaseOption{Type: CollateType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 170: + case 173: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1380 +//line sql.y:1396 { yyVAL.databaseOption = DatabaseOption{Type: CollateType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 171: + case 174: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1386 +//line sql.y:1402 { yyVAL.databaseOption = DatabaseOption{Type: EncryptionType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 172: + case 175: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1390 +//line sql.y:1406 { yyVAL.databaseOption = DatabaseOption{Type: EncryptionType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 173: + case 176: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OptLike -//line sql.y:1396 +//line sql.y:1412 { yyLOCAL = &OptLike{LikeTable: yyDollar[2].tableName} } yyVAL.union = yyLOCAL - case 174: + case 177: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OptLike -//line sql.y:1400 +//line sql.y:1416 { yyLOCAL = &OptLike{LikeTable: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 175: + case 178: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColumnDefinition -//line sql.y:1406 +//line sql.y:1422 { yyLOCAL = []*ColumnDefinition{yyDollar[1].columnDefinitionUnion()} } yyVAL.union = yyLOCAL - case 176: + case 179: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1410 +//line sql.y:1426 { yySLICE := (*[]*ColumnDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].columnDefinitionUnion()) } - case 177: + case 180: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1416 +//line sql.y:1432 { yyLOCAL = &TableSpec{} yyLOCAL.AddColumn(yyDollar[1].columnDefinitionUnion()) } yyVAL.union = yyLOCAL - case 178: + case 181: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1421 +//line sql.y:1437 { yyLOCAL = &TableSpec{} yyLOCAL.AddConstraint(yyDollar[1].constraintDefinitionUnion()) } yyVAL.union = yyLOCAL - case 179: + case 182: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1426 +//line sql.y:1442 { yyVAL.tableSpecUnion().AddColumn(yyDollar[3].columnDefinitionUnion()) } - case 180: + case 183: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1430 +//line sql.y:1446 { yyVAL.tableSpecUnion().AddColumn(yyDollar[3].columnDefinitionUnion()) yyVAL.tableSpecUnion().AddConstraint(yyDollar[4].constraintDefinitionUnion()) } - case 181: + case 184: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1435 +//line sql.y:1451 { yyVAL.tableSpecUnion().AddIndex(yyDollar[3].indexDefinitionUnion()) } - case 182: + case 185: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1439 +//line sql.y:1455 { yyVAL.tableSpecUnion().AddConstraint(yyDollar[3].constraintDefinitionUnion()) } - case 183: + case 186: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1443 +//line sql.y:1459 { yyVAL.tableSpecUnion().AddConstraint(yyDollar[3].constraintDefinitionUnion()) } - case 184: + case 187: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColumnDefinition -//line sql.y:1454 +//line sql.y:1470 { yyDollar[2].columnType.Options = yyDollar[4].columnTypeOptionsUnion() if yyDollar[2].columnType.Options.Collate == "" { @@ -11563,10 +11568,10 @@ yydefault: yyLOCAL = &ColumnDefinition{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType} } yyVAL.union = yyLOCAL - case 185: + case 188: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL *ColumnDefinition -//line sql.y:1463 +//line sql.y:1479 { yyDollar[2].columnType.Options = yyDollar[9].columnTypeOptionsUnion() yyDollar[2].columnType.Options.As = yyDollar[7].exprUnion() @@ -11575,945 +11580,921 @@ yydefault: yyLOCAL = &ColumnDefinition{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType} } yyVAL.union = yyLOCAL - case 186: + case 189: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1472 +//line sql.y:1488 { yyVAL.str = "" } - case 187: + case 190: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1476 +//line sql.y:1492 { yyVAL.str = "" } - case 188: + case 191: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1485 +//line sql.y:1501 { yyLOCAL = &ColumnTypeOptions{Null: nil, Default: nil, OnUpdate: nil, Autoincrement: false, KeyOpt: ColKeyNone, Comment: nil, As: nil, Invisible: nil, Format: UnspecifiedFormat, EngineAttribute: nil, SecondaryEngineAttribute: nil} } yyVAL.union = yyLOCAL - case 189: + case 192: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1489 +//line sql.y:1505 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 190: + case 193: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1494 +//line sql.y:1510 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 191: + case 194: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1499 +//line sql.y:1515 { yyDollar[1].columnTypeOptionsUnion().Default = yyDollar[4].exprUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 192: + case 195: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1504 +//line sql.y:1520 { yyDollar[1].columnTypeOptionsUnion().Default = yyDollar[3].exprUnion() yyDollar[1].columnTypeOptionsUnion().DefaultLiteral = true yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 193: + case 196: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1510 +//line sql.y:1526 { yyDollar[1].columnTypeOptionsUnion().OnUpdate = yyDollar[4].exprUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 194: + case 197: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1515 +//line sql.y:1531 { yyDollar[1].columnTypeOptionsUnion().Autoincrement = true yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 195: + case 198: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1520 +//line sql.y:1536 { yyDollar[1].columnTypeOptionsUnion().Comment = NewStrLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 196: + case 199: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1525 +//line sql.y:1541 { yyDollar[1].columnTypeOptionsUnion().KeyOpt = yyDollar[2].colKeyOptUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 197: + case 200: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1530 +//line sql.y:1546 { yyDollar[1].columnTypeOptionsUnion().Collate = encodeSQLString(yyDollar[3].str) } - case 198: + case 201: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1534 +//line sql.y:1550 { yyDollar[1].columnTypeOptionsUnion().Collate = string(yyDollar[3].identifierCI.String()) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 199: + case 202: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1539 +//line sql.y:1555 { yyDollar[1].columnTypeOptionsUnion().Format = yyDollar[3].columnFormatUnion() } - case 200: + case 203: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1543 +//line sql.y:1559 { yyDollar[1].columnTypeOptionsUnion().SRID = NewIntLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 201: + case 204: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1548 +//line sql.y:1564 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 202: + case 205: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1553 +//line sql.y:1569 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 203: + case 206: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1558 +//line sql.y:1574 { yyDollar[1].columnTypeOptionsUnion().EngineAttribute = NewStrLiteral(yyDollar[4].str) } - case 204: + case 207: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1562 +//line sql.y:1578 { yyDollar[1].columnTypeOptionsUnion().SecondaryEngineAttribute = NewStrLiteral(yyDollar[4].str) } - case 205: + case 208: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1568 +//line sql.y:1584 { yyLOCAL = FixedFormat } yyVAL.union = yyLOCAL - case 206: + case 209: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1572 +//line sql.y:1588 { yyLOCAL = DynamicFormat } yyVAL.union = yyLOCAL - case 207: + case 210: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1576 +//line sql.y:1592 { yyLOCAL = DefaultFormat } yyVAL.union = yyLOCAL - case 208: + case 211: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnStorage -//line sql.y:1582 +//line sql.y:1598 { yyLOCAL = VirtualStorage } yyVAL.union = yyLOCAL - case 209: + case 212: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnStorage -//line sql.y:1586 +//line sql.y:1602 { yyLOCAL = StoredStorage } yyVAL.union = yyLOCAL - case 210: + case 213: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1591 +//line sql.y:1607 { yyLOCAL = &ColumnTypeOptions{} } yyVAL.union = yyLOCAL - case 211: + case 214: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1595 +//line sql.y:1611 { yyDollar[1].columnTypeOptionsUnion().Storage = yyDollar[2].columnStorageUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 212: + case 215: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1600 +//line sql.y:1616 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 213: + case 216: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1605 +//line sql.y:1621 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 214: + case 217: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1610 +//line sql.y:1626 { yyDollar[1].columnTypeOptionsUnion().Comment = NewStrLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 215: + case 218: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1615 +//line sql.y:1631 { yyDollar[1].columnTypeOptionsUnion().KeyOpt = yyDollar[2].colKeyOptUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 216: + case 219: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1620 +//line sql.y:1636 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 217: + case 220: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1625 +//line sql.y:1641 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 218: + case 221: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1632 +//line sql.y:1648 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 220: + case 223: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1639 +//line sql.y:1655 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_timestamp"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 221: + case 224: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1643 +//line sql.y:1659 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("localtime"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 222: + case 225: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1647 +//line sql.y:1663 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("localtimestamp"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 223: + case 226: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1651 +//line sql.y:1667 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_timestamp"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 224: + case 227: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1655 +//line sql.y:1671 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("now"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 225: + case 228: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1659 +//line sql.y:1675 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("sysdate"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 228: + case 231: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1669 +//line sql.y:1685 { yyLOCAL = &NullVal{} } yyVAL.union = yyLOCAL - case 230: + case 233: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1676 +//line sql.y:1692 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 231: + case 234: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1680 +//line sql.y:1696 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 232: + case 235: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1686 +//line sql.y:1702 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 233: + case 236: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1690 +//line sql.y:1706 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 234: + case 237: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1694 +//line sql.y:1710 { yyLOCAL = yyDollar[1].boolValUnion() } yyVAL.union = yyLOCAL - case 235: + case 238: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1698 +//line sql.y:1714 { yyLOCAL = NewHexLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 236: + case 239: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1702 +//line sql.y:1718 { yyLOCAL = NewHexNumLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 237: + case 240: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1706 +//line sql.y:1722 { yyLOCAL = NewBitLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 238: + case 241: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1710 +//line sql.y:1726 { yyLOCAL = NewBitLiteral("0b" + yyDollar[1].str) } yyVAL.union = yyLOCAL - case 239: + case 242: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1714 +//line sql.y:1730 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 240: + case 243: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1718 +//line sql.y:1734 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral("0b" + yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 241: + case 244: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1722 +//line sql.y:1738 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexNumLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 242: + case 245: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1726 +//line sql.y:1742 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 243: + case 246: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1730 +//line sql.y:1746 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 244: + case 247: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1734 +//line sql.y:1750 { arg := parseBindVariable(yylex, yyDollar[2].str[1:]) yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: arg} } yyVAL.union = yyLOCAL - case 245: + case 248: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1739 +//line sql.y:1755 { yyLOCAL = NewDateLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 246: + case 249: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1743 +//line sql.y:1759 { yyLOCAL = NewTimeLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 247: + case 250: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1747 +//line sql.y:1763 { yyLOCAL = NewTimestampLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 248: + case 251: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1753 +//line sql.y:1769 { yyVAL.str = Armscii8Str } - case 249: + case 252: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1757 +//line sql.y:1773 { yyVAL.str = ASCIIStr } - case 250: + case 253: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1761 +//line sql.y:1777 { yyVAL.str = Big5Str } - case 251: + case 254: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1765 +//line sql.y:1781 { yyVAL.str = UBinaryStr } - case 252: + case 255: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1769 +//line sql.y:1785 { yyVAL.str = Cp1250Str } - case 253: + case 256: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1773 +//line sql.y:1789 { yyVAL.str = Cp1251Str } - case 254: + case 257: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1777 +//line sql.y:1793 { yyVAL.str = Cp1256Str } - case 255: + case 258: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1781 +//line sql.y:1797 { yyVAL.str = Cp1257Str } - case 256: + case 259: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1785 +//line sql.y:1801 { yyVAL.str = Cp850Str } - case 257: + case 260: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1789 +//line sql.y:1805 { yyVAL.str = Cp852Str } - case 258: + case 261: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1793 +//line sql.y:1809 { yyVAL.str = Cp866Str } - case 259: + case 262: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1797 +//line sql.y:1813 { yyVAL.str = Cp932Str } - case 260: + case 263: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1801 +//line sql.y:1817 { yyVAL.str = Dec8Str } - case 261: + case 264: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1805 +//line sql.y:1821 { yyVAL.str = EucjpmsStr } - case 262: + case 265: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1809 +//line sql.y:1825 { yyVAL.str = EuckrStr } - case 263: + case 266: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1813 +//line sql.y:1829 { yyVAL.str = Gb18030Str } - case 264: + case 267: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1817 +//line sql.y:1833 { yyVAL.str = Gb2312Str } - case 265: + case 268: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1821 +//line sql.y:1837 { yyVAL.str = GbkStr } - case 266: + case 269: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1825 +//line sql.y:1841 { yyVAL.str = Geostd8Str } - case 267: + case 270: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1829 +//line sql.y:1845 { yyVAL.str = GreekStr } - case 268: + case 271: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1833 +//line sql.y:1849 { yyVAL.str = HebrewStr } - case 269: + case 272: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1837 +//line sql.y:1853 { yyVAL.str = Hp8Str } - case 270: + case 273: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1841 +//line sql.y:1857 { yyVAL.str = Keybcs2Str } - case 271: + case 274: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1845 +//line sql.y:1861 { yyVAL.str = Koi8rStr } - case 272: + case 275: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1849 +//line sql.y:1865 { yyVAL.str = Koi8uStr } - case 273: + case 276: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1853 +//line sql.y:1869 { yyVAL.str = Latin1Str } - case 274: + case 277: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1857 +//line sql.y:1873 { yyVAL.str = Latin2Str } - case 275: + case 278: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1861 +//line sql.y:1877 { yyVAL.str = Latin5Str } - case 276: + case 279: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1865 +//line sql.y:1881 { yyVAL.str = Latin7Str } - case 277: + case 280: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1869 +//line sql.y:1885 { yyVAL.str = MacceStr } - case 278: + case 281: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1873 +//line sql.y:1889 { yyVAL.str = MacromanStr } - case 279: + case 282: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1877 +//line sql.y:1893 { yyVAL.str = SjisStr } - case 280: + case 283: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1881 +//line sql.y:1897 { yyVAL.str = Swe7Str } - case 281: + case 284: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1885 +//line sql.y:1901 { yyVAL.str = Tis620Str } - case 282: + case 285: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1889 +//line sql.y:1905 { yyVAL.str = Ucs2Str } - case 283: + case 286: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1893 +//line sql.y:1909 { yyVAL.str = UjisStr } - case 284: + case 287: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1897 +//line sql.y:1913 { yyVAL.str = Utf16Str } - case 285: + case 288: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1901 +//line sql.y:1917 { yyVAL.str = Utf16leStr } - case 286: + case 289: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1905 +//line sql.y:1921 { yyVAL.str = Utf32Str } - case 287: + case 290: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1909 +//line sql.y:1925 { yyVAL.str = Utf8mb3Str } - case 288: + case 291: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1913 +//line sql.y:1929 { yyVAL.str = Utf8mb4Str } - case 289: + case 292: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1917 +//line sql.y:1933 { yyVAL.str = Utf8mb3Str } - case 292: + case 295: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1927 +//line sql.y:1943 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 293: + case 296: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1931 +//line sql.y:1947 { yyLOCAL = NewFloatLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 294: + case 297: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1935 +//line sql.y:1951 { yyLOCAL = NewDecimalLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 295: + case 298: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1941 +//line sql.y:1957 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 296: + case 299: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1945 +//line sql.y:1961 { yyLOCAL = AppendString(yyDollar[1].exprUnion(), yyDollar[2].str) } yyVAL.union = yyLOCAL - case 297: + case 300: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1951 +//line sql.y:1967 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 298: + case 301: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1955 +//line sql.y:1971 { yyLOCAL = &UnaryExpr{Operator: NStringOp, Expr: NewStrLiteral(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 299: + case 302: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1959 +//line sql.y:1975 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewStrLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 300: + case 303: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1965 +//line sql.y:1981 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 301: + case 304: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1969 +//line sql.y:1985 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 302: + case 305: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1975 +//line sql.y:1991 { yyLOCAL = ColKeyPrimary } yyVAL.union = yyLOCAL - case 303: + case 306: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1979 +//line sql.y:1995 { yyLOCAL = ColKeyUnique } yyVAL.union = yyLOCAL - case 304: + case 307: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1983 +//line sql.y:1999 { yyLOCAL = ColKeyUniqueKey } yyVAL.union = yyLOCAL - case 305: + case 308: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1987 +//line sql.y:2003 { yyLOCAL = ColKey } yyVAL.union = yyLOCAL - case 306: + case 309: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1993 +//line sql.y:2009 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Unsigned = yyDollar[2].booleanUnion() yyVAL.columnType.Zerofill = yyDollar[3].booleanUnion() } - case 310: + case 313: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2004 +//line sql.y:2020 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Length = yyDollar[2].intPtrUnion() } - case 311: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2009 - { - yyVAL.columnType = yyDollar[1].columnType - } - case 312: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2015 - { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} - } - case 313: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2019 - { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} - } case 314: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2023 +//line sql.y:2025 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType = yyDollar[1].columnType } case 315: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2027 +//line sql.y:2031 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 316: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2031 +//line sql.y:2035 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 317: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2035 +//line sql.y:2039 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 318: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2039 +//line sql.y:2043 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 319: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2043 +//line sql.y:2047 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 320: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2047 +//line sql.y:2051 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 321: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2053 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2055 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} - yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 322: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2059 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} - yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 323: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2065 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2063 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} - yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 324: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2071 +//line sql.y:2069 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12521,7 +12502,7 @@ yydefault: } case 325: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2077 +//line sql.y:2075 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12529,7 +12510,7 @@ yydefault: } case 326: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2083 +//line sql.y:2081 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12537,1763 +12518,1787 @@ yydefault: } case 327: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2089 +//line sql.y:2087 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 328: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2097 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2093 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 329: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2101 +//line sql.y:2099 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 330: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2105 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 331: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2109 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2113 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 332: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2113 +//line sql.y:2117 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 333: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2121 + { + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + } + case 334: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2125 + { + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + } + case 335: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2129 + { + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + } + case 336: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2119 +//line sql.y:2135 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } - case 334: + case 337: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2123 +//line sql.y:2139 { // CHAR BYTE is an alias for binary. See also: // https://dev.mysql.com/doc/refman/8.0/en/string-type-syntax.html yyVAL.columnType = &ColumnType{Type: "binary", Length: yyDollar[2].intPtrUnion()} } - case 335: + case 338: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2129 +//line sql.y:2145 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } - case 336: + case 339: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2133 +//line sql.y:2149 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } - case 337: + case 340: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2137 +//line sql.y:2153 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } - case 338: + case 341: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2141 +//line sql.y:2157 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } - case 339: + case 342: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2145 +//line sql.y:2161 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } - case 340: + case 343: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2149 +//line sql.y:2165 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } - case 341: + case 344: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2153 +//line sql.y:2169 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } - case 342: + case 345: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2157 +//line sql.y:2173 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 343: + case 346: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2161 +//line sql.y:2177 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 344: + case 347: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2165 +//line sql.y:2181 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 345: + case 348: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2169 +//line sql.y:2185 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 346: + case 349: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2173 +//line sql.y:2189 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 347: + case 350: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2177 +//line sql.y:2193 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].columnCharset} } - case 348: + case 351: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2181 +//line sql.y:2197 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } - case 349: + case 352: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2186 +//line sql.y:2202 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].columnCharset} } - case 350: + case 353: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2192 +//line sql.y:2208 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 351: + case 354: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2196 +//line sql.y:2212 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 352: + case 355: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2200 +//line sql.y:2216 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 353: + case 356: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2204 +//line sql.y:2220 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 354: + case 357: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2208 +//line sql.y:2224 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 355: + case 358: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2212 +//line sql.y:2228 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 356: + case 359: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2216 +//line sql.y:2232 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 357: + case 360: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2220 +//line sql.y:2236 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } - case 358: + case 361: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2226 +//line sql.y:2242 { yyVAL.strs = make([]string, 0, 4) yyVAL.strs = append(yyVAL.strs, encodeSQLString(yyDollar[1].str)) } - case 359: + case 362: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2231 +//line sql.y:2247 { yyVAL.strs = append(yyDollar[1].strs, encodeSQLString(yyDollar[3].str)) } - case 360: + case 363: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *int -//line sql.y:2236 +//line sql.y:2252 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 361: + case 364: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *int -//line sql.y:2240 +//line sql.y:2256 { yyLOCAL = ptr.Of(convertStringToInt(yyDollar[2].str)) } yyVAL.union = yyLOCAL - case 362: + case 365: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2245 +//line sql.y:2261 { yyVAL.LengthScaleOption = LengthScaleOption{} } - case 363: + case 366: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2249 +//line sql.y:2265 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), Scale: ptr.Of(convertStringToInt(yyDollar[4].str)), } } - case 364: + case 367: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2258 +//line sql.y:2274 { yyVAL.LengthScaleOption = yyDollar[1].LengthScaleOption } - case 365: + case 368: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2262 +//line sql.y:2278 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), } } - case 366: + case 369: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2269 +//line sql.y:2285 { yyVAL.LengthScaleOption = LengthScaleOption{} } - case 367: + case 370: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2273 +//line sql.y:2289 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), } } - case 368: + case 371: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2279 +//line sql.y:2295 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), Scale: ptr.Of(convertStringToInt(yyDollar[4].str)), } } - case 369: + case 372: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2287 +//line sql.y:2303 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 370: + case 373: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2291 +//line sql.y:2307 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 371: + case 374: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2295 +//line sql.y:2311 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 372: + case 375: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2300 +//line sql.y:2316 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 373: + case 376: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2304 +//line sql.y:2320 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 374: + case 377: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2309 +//line sql.y:2325 { yyVAL.columnCharset = ColumnCharset{} } - case 375: + case 378: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2313 +//line sql.y:2329 { yyVAL.columnCharset = ColumnCharset{Name: string(yyDollar[2].identifierCI.String()), Binary: yyDollar[3].booleanUnion()} } - case 376: + case 379: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2317 +//line sql.y:2333 { yyVAL.columnCharset = ColumnCharset{Name: encodeSQLString(yyDollar[2].str), Binary: yyDollar[3].booleanUnion()} } - case 377: + case 380: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2321 +//line sql.y:2337 { yyVAL.columnCharset = ColumnCharset{Name: string(yyDollar[2].str)} } - case 378: + case 381: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2325 +//line sql.y:2341 { // ASCII: Shorthand for CHARACTER SET latin1. yyVAL.columnCharset = ColumnCharset{Name: "latin1", Binary: yyDollar[2].booleanUnion()} } - case 379: + case 382: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2330 +//line sql.y:2346 { // UNICODE: Shorthand for CHARACTER SET ucs2. yyVAL.columnCharset = ColumnCharset{Name: "ucs2", Binary: yyDollar[2].booleanUnion()} } - case 380: + case 383: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2335 +//line sql.y:2351 { // BINARY: Shorthand for default CHARACTER SET but with binary collation yyVAL.columnCharset = ColumnCharset{Name: "", Binary: true} } - case 381: + case 384: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2340 +//line sql.y:2356 { // BINARY ASCII: Shorthand for CHARACTER SET latin1 with binary collation yyVAL.columnCharset = ColumnCharset{Name: "latin1", Binary: true} } - case 382: + case 385: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2345 +//line sql.y:2361 { // BINARY UNICODE: Shorthand for CHARACTER SET ucs2 with binary collation yyVAL.columnCharset = ColumnCharset{Name: "ucs2", Binary: true} } - case 383: + case 386: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2351 +//line sql.y:2367 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 384: + case 387: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2355 +//line sql.y:2371 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 385: + case 388: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2360 +//line sql.y:2376 { yyVAL.str = "" } - case 386: + case 389: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2364 +//line sql.y:2380 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } - case 387: + case 390: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2368 +//line sql.y:2384 { yyVAL.str = encodeSQLString(yyDollar[2].str) } - case 388: + case 391: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexDefinition -//line sql.y:2374 +//line sql.y:2390 { yyLOCAL = &IndexDefinition{Info: yyDollar[1].indexInfoUnion(), Columns: yyDollar[3].indexColumnsUnion(), Options: yyDollar[5].indexOptionsUnion()} } yyVAL.union = yyLOCAL - case 389: + case 392: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2379 +//line sql.y:2395 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 390: + case 393: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2383 +//line sql.y:2399 { yyLOCAL = yyDollar[1].indexOptionsUnion() } yyVAL.union = yyLOCAL - case 391: + case 394: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2389 +//line sql.y:2405 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 392: + case 395: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2393 +//line sql.y:2409 { yySLICE := (*[]*IndexOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexOptionUnion()) } - case 393: + case 396: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2399 +//line sql.y:2415 { yyLOCAL = yyDollar[1].indexOptionUnion() } yyVAL.union = yyLOCAL - case 394: + case 397: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2403 +//line sql.y:2419 { // should not be string yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 395: + case 398: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2408 +//line sql.y:2424 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 396: + case 399: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2412 +//line sql.y:2428 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 397: + case 400: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2416 +//line sql.y:2432 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 398: + case 401: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2420 +//line sql.y:2436 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str) + " " + string(yyDollar[2].str), String: yyDollar[3].identifierCI.String()} } yyVAL.union = yyLOCAL - case 399: + case 402: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2424 +//line sql.y:2440 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 400: + case 403: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2428 +//line sql.y:2444 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 401: + case 404: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2434 +//line sql.y:2450 { yyVAL.str = "" } - case 402: + case 405: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2438 +//line sql.y:2454 { yyVAL.str = string(yyDollar[1].str) } - case 403: + case 406: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2444 +//line sql.y:2460 { yyLOCAL = &IndexInfo{Type: IndexTypePrimary, ConstraintName: NewIdentifierCI(yyDollar[1].str), Name: NewIdentifierCI("PRIMARY")} } yyVAL.union = yyLOCAL - case 404: + case 407: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2448 +//line sql.y:2464 { yyLOCAL = &IndexInfo{Type: IndexTypeSpatial, Name: NewIdentifierCI(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 405: + case 408: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2452 +//line sql.y:2468 { yyLOCAL = &IndexInfo{Type: IndexTypeFullText, Name: NewIdentifierCI(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 406: + case 409: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2456 +//line sql.y:2472 { yyLOCAL = &IndexInfo{Type: IndexTypeUnique, ConstraintName: NewIdentifierCI(yyDollar[1].str), Name: NewIdentifierCI(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 407: + case 410: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2460 +//line sql.y:2476 { yyLOCAL = &IndexInfo{Type: IndexTypeDefault, Name: NewIdentifierCI(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 408: + case 411: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2465 +//line sql.y:2481 { yyVAL.str = "" } - case 409: + case 412: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2469 +//line sql.y:2485 { yyVAL.str = yyDollar[2].str } - case 410: + case 413: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2475 +//line sql.y:2491 { yyVAL.str = string(yyDollar[1].str) } - case 411: + case 414: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2479 +//line sql.y:2495 { yyVAL.str = string(yyDollar[1].str) } - case 412: + case 415: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2483 +//line sql.y:2499 { yyVAL.str = string(yyDollar[1].str) } - case 413: + case 416: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2489 +//line sql.y:2505 { yyVAL.str = string(yyDollar[1].str) } - case 414: + case 417: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2493 +//line sql.y:2509 { yyVAL.str = string(yyDollar[1].str) } - case 415: + case 418: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2498 +//line sql.y:2514 { yyVAL.str = "" } - case 416: + case 419: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2502 +//line sql.y:2518 { yyVAL.str = yyDollar[1].str } - case 417: + case 420: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2508 +//line sql.y:2524 { yyVAL.str = string(yyDollar[1].str) } - case 418: + case 421: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2512 +//line sql.y:2528 { yyVAL.str = string(yyDollar[1].str) } - case 419: + case 422: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2517 +//line sql.y:2533 { yyVAL.str = "" } - case 420: + case 423: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2521 +//line sql.y:2537 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } - case 421: + case 424: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexColumn -//line sql.y:2527 +//line sql.y:2543 { yyLOCAL = []*IndexColumn{yyDollar[1].indexColumnUnion()} } yyVAL.union = yyLOCAL - case 422: + case 425: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2531 +//line sql.y:2547 { yySLICE := (*[]*IndexColumn)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].indexColumnUnion()) } - case 423: + case 426: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexColumn -//line sql.y:2537 +//line sql.y:2553 { yyLOCAL = &IndexColumn{Column: yyDollar[1].identifierCI, Length: yyDollar[2].intPtrUnion(), Direction: yyDollar[3].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 424: + case 427: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexColumn -//line sql.y:2541 +//line sql.y:2557 { yyLOCAL = &IndexColumn{Expression: yyDollar[2].exprUnion(), Direction: yyDollar[4].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 425: + case 428: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2547 +//line sql.y:2563 { yyLOCAL = &ConstraintDefinition{Name: yyDollar[2].identifierCI, Details: yyDollar[3].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 426: + case 429: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2551 +//line sql.y:2567 { yyLOCAL = &ConstraintDefinition{Details: yyDollar[1].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 427: + case 430: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2557 +//line sql.y:2573 { yyLOCAL = &ConstraintDefinition{Name: yyDollar[2].identifierCI, Details: yyDollar[3].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 428: + case 431: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2561 +//line sql.y:2577 { yyLOCAL = &ConstraintDefinition{Details: yyDollar[1].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 429: + case 432: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL ConstraintInfo -//line sql.y:2567 +//line sql.y:2583 { yyLOCAL = &ForeignKeyDefinition{IndexName: NewIdentifierCI(yyDollar[3].str), Source: yyDollar[5].columnsUnion(), ReferenceDefinition: yyDollar[7].referenceDefinitionUnion()} } yyVAL.union = yyLOCAL - case 430: + case 433: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2573 +//line sql.y:2589 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion()} } yyVAL.union = yyLOCAL - case 431: + case 434: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2577 +//line sql.y:2593 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnDelete: yyDollar[7].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 432: + case 435: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2581 +//line sql.y:2597 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnUpdate: yyDollar[7].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 433: + case 436: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2585 +//line sql.y:2601 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnDelete: yyDollar[7].referenceActionUnion(), OnUpdate: yyDollar[8].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 434: + case 437: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2589 +//line sql.y:2605 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnUpdate: yyDollar[7].referenceActionUnion(), OnDelete: yyDollar[8].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 435: + case 438: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2594 +//line sql.y:2610 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 436: + case 439: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2598 +//line sql.y:2614 { yyLOCAL = yyDollar[1].referenceDefinitionUnion() } yyVAL.union = yyLOCAL - case 437: + case 440: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL ConstraintInfo -//line sql.y:2604 +//line sql.y:2620 { yyLOCAL = &CheckConstraintDefinition{Expr: yyDollar[3].exprUnion(), Enforced: yyDollar[5].booleanUnion()} } yyVAL.union = yyLOCAL - case 438: + case 441: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2610 +//line sql.y:2626 { yyLOCAL = yyDollar[2].matchActionUnion() } yyVAL.union = yyLOCAL - case 439: + case 442: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2616 +//line sql.y:2632 { yyLOCAL = Full } yyVAL.union = yyLOCAL - case 440: + case 443: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2620 +//line sql.y:2636 { yyLOCAL = Partial } yyVAL.union = yyLOCAL - case 441: + case 444: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2624 +//line sql.y:2640 { yyLOCAL = Simple } yyVAL.union = yyLOCAL - case 442: + case 445: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2629 +//line sql.y:2645 { yyLOCAL = DefaultMatch } yyVAL.union = yyLOCAL - case 443: + case 446: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2633 +//line sql.y:2649 { yyLOCAL = yyDollar[1].matchActionUnion() } yyVAL.union = yyLOCAL - case 444: + case 447: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2639 +//line sql.y:2655 { yyLOCAL = yyDollar[3].referenceActionUnion() } yyVAL.union = yyLOCAL - case 445: + case 448: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2645 +//line sql.y:2661 { yyLOCAL = yyDollar[3].referenceActionUnion() } yyVAL.union = yyLOCAL - case 446: + case 449: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2651 +//line sql.y:2667 { yyLOCAL = Restrict } yyVAL.union = yyLOCAL - case 447: + case 450: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2655 +//line sql.y:2671 { yyLOCAL = Cascade } yyVAL.union = yyLOCAL - case 448: + case 451: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2659 +//line sql.y:2675 { yyLOCAL = NoAction } yyVAL.union = yyLOCAL - case 449: + case 452: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2663 +//line sql.y:2679 { yyLOCAL = SetDefault } yyVAL.union = yyLOCAL - case 450: + case 453: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2667 +//line sql.y:2683 { yyLOCAL = SetNull } yyVAL.union = yyLOCAL - case 451: + case 454: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2672 +//line sql.y:2688 { yyVAL.str = "" } - case 452: + case 455: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2676 +//line sql.y:2692 { yyVAL.str = string(yyDollar[1].str) } - case 453: + case 456: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2680 +//line sql.y:2696 { yyVAL.str = string(yyDollar[1].str) } - case 454: + case 457: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2686 +//line sql.y:2702 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 455: + case 458: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:2690 +//line sql.y:2706 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 456: + case 459: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2695 +//line sql.y:2711 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 457: + case 460: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2699 +//line sql.y:2715 { yyLOCAL = yyDollar[1].booleanUnion() } yyVAL.union = yyLOCAL - case 458: + case 461: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2704 +//line sql.y:2720 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 459: + case 462: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2708 +//line sql.y:2724 { yyLOCAL = yyDollar[1].tableOptionsUnion() } yyVAL.union = yyLOCAL - case 460: + case 463: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2714 +//line sql.y:2730 { yyLOCAL = TableOptions{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL - case 461: + case 464: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2718 +//line sql.y:2734 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableOptionUnion()) } - case 462: + case 465: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2722 +//line sql.y:2738 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].tableOptionUnion()) } - case 463: + case 466: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2728 +//line sql.y:2744 { yyLOCAL = TableOptions{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL - case 464: + case 467: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2732 +//line sql.y:2748 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].tableOptionUnion()) } - case 465: + case 468: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2738 +//line sql.y:2754 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 466: + case 469: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2742 +//line sql.y:2758 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 467: + case 470: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2746 +//line sql.y:2762 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 468: + case 471: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2750 +//line sql.y:2766 { yyLOCAL = &TableOption{Name: (string(yyDollar[2].str)), String: yyDollar[4].str, CaseSensitive: true} } yyVAL.union = yyLOCAL - case 469: + case 472: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2754 +//line sql.y:2770 { yyLOCAL = &TableOption{Name: string(yyDollar[2].str), String: yyDollar[4].str, CaseSensitive: true} } yyVAL.union = yyLOCAL - case 470: + case 473: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2758 +//line sql.y:2774 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 471: + case 474: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2762 +//line sql.y:2778 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 472: + case 475: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2766 +//line sql.y:2782 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 473: + case 476: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2770 +//line sql.y:2786 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 474: + case 477: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2774 +//line sql.y:2790 { yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 475: + case 478: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2778 +//line sql.y:2794 { yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 476: + case 479: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2782 +//line sql.y:2798 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 477: + case 480: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2786 +//line sql.y:2802 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 478: + case 481: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2790 +//line sql.y:2806 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: yyDollar[3].identifierCS.String(), CaseSensitive: true} } yyVAL.union = yyLOCAL - case 479: + case 482: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2794 +//line sql.y:2810 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 480: + case 483: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2798 +//line sql.y:2814 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 481: + case 484: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2802 +//line sql.y:2818 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 482: + case 485: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2806 +//line sql.y:2822 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 483: + case 486: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2810 +//line sql.y:2826 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 484: + case 487: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2814 +//line sql.y:2830 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 485: + case 488: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2818 +//line sql.y:2834 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 486: + case 489: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2822 +//line sql.y:2838 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 487: + case 490: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2826 +//line sql.y:2842 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 488: + case 491: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2830 +//line sql.y:2846 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 489: + case 492: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2834 +//line sql.y:2850 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 490: + case 493: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2838 +//line sql.y:2854 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 491: + case 494: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2842 +//line sql.y:2858 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 492: + case 495: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2846 +//line sql.y:2862 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 493: + case 496: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2850 +//line sql.y:2866 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 494: + case 497: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2854 +//line sql.y:2870 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: (yyDollar[3].identifierCI.String() + yyDollar[4].str), CaseSensitive: true} } yyVAL.union = yyLOCAL - case 495: + case 498: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2858 +//line sql.y:2874 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Tables: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL - case 496: + case 499: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2863 +//line sql.y:2879 { yyVAL.str = "" } - case 497: + case 500: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2867 +//line sql.y:2883 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 498: + case 501: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2871 +//line sql.y:2887 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 508: + case 511: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2890 +//line sql.y:2906 { yyVAL.str = String(TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}) } - case 509: + case 512: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2894 +//line sql.y:2910 { yyVAL.str = yyDollar[1].identifierCI.String() } - case 510: + case 513: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2898 +//line sql.y:2914 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 511: + case 514: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2902 +//line sql.y:2918 { yyVAL.str = string(yyDollar[1].str) } - case 512: + case 515: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2907 +//line sql.y:2923 { yyVAL.str = "" } - case 514: + case 517: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2913 +//line sql.y:2929 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 515: + case 518: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2917 +//line sql.y:2933 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 516: + case 519: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColName -//line sql.y:2922 +//line sql.y:2938 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 517: + case 520: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColName -//line sql.y:2926 +//line sql.y:2942 { yyLOCAL = yyDollar[2].colNameUnion() } yyVAL.union = yyLOCAL - case 518: + case 521: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2931 +//line sql.y:2947 { yyVAL.str = "" } - case 519: + case 522: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2935 +//line sql.y:2951 { yyVAL.str = string(yyDollar[2].str) } - case 520: + case 523: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Literal -//line sql.y:2940 +//line sql.y:2956 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 521: + case 524: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Literal -//line sql.y:2944 +//line sql.y:2960 { yyLOCAL = NewIntLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 522: + case 525: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Literal -//line sql.y:2948 +//line sql.y:2964 { yyLOCAL = NewDecimalLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 523: + case 526: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2953 +//line sql.y:2969 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 524: + case 527: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2957 +//line sql.y:2973 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL - case 525: + case 528: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2961 +//line sql.y:2977 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &OrderByOption{Cols: yyDollar[5].columnsUnion()}) } - case 526: + case 529: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2965 +//line sql.y:2981 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL - case 527: + case 530: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2969 +//line sql.y:2985 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionsUnion()...) } - case 528: + case 531: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2973 +//line sql.y:2989 { yyLOCAL = append(append(yyDollar[1].alterOptionsUnion(), yyDollar[3].alterOptionsUnion()...), &OrderByOption{Cols: yyDollar[7].columnsUnion()}) } yyVAL.union = yyLOCAL - case 529: + case 532: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2979 +//line sql.y:2995 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 530: + case 533: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2983 +//line sql.y:2999 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - case 531: + case 534: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2987 +//line sql.y:3003 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - case 532: + case 535: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2993 +//line sql.y:3009 { yyLOCAL = yyDollar[1].tableOptionsUnion() } yyVAL.union = yyLOCAL - case 533: + case 536: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2997 +//line sql.y:3013 { yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} } yyVAL.union = yyLOCAL - case 534: + case 537: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3001 +//line sql.y:3017 { yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} } yyVAL.union = yyLOCAL - case 535: + case 538: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3005 +//line sql.y:3021 { yyLOCAL = &AddIndexDefinition{IndexDefinition: yyDollar[2].indexDefinitionUnion()} } yyVAL.union = yyLOCAL - case 536: + case 539: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3009 +//line sql.y:3025 { yyLOCAL = &AddColumns{Columns: yyDollar[4].columnDefinitionsUnion()} } yyVAL.union = yyLOCAL - case 537: + case 540: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3013 +//line sql.y:3029 { yyLOCAL = &AddColumns{Columns: []*ColumnDefinition{yyDollar[3].columnDefinitionUnion()}, First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL - case 538: + case 541: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3017 +//line sql.y:3033 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: true} } yyVAL.union = yyLOCAL - case 539: + case 542: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3021 +//line sql.y:3037 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[6].exprUnion(), DefaultLiteral: true} } yyVAL.union = yyLOCAL - case 540: + case 543: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3025 +//line sql.y:3041 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 541: + case 544: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3029 +//line sql.y:3045 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(false)} } yyVAL.union = yyLOCAL - case 542: + case 545: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3033 +//line sql.y:3049 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(true)} } yyVAL.union = yyLOCAL - case 543: + case 546: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3037 +//line sql.y:3053 { yyLOCAL = &AlterCheck{Name: yyDollar[3].identifierCI, Enforced: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 544: + case 547: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3041 +//line sql.y:3057 { yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: false} } yyVAL.union = yyLOCAL - case 545: + case 548: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3045 +//line sql.y:3061 { yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: true} } yyVAL.union = yyLOCAL - case 546: + case 549: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3049 +//line sql.y:3065 { yyLOCAL = &ChangeColumn{OldColumn: yyDollar[3].colNameUnion(), NewColDefinition: yyDollar[4].columnDefinitionUnion(), First: yyDollar[5].booleanUnion(), After: yyDollar[6].colNameUnion()} } yyVAL.union = yyLOCAL - case 547: + case 550: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3053 +//line sql.y:3069 { yyLOCAL = &ModifyColumn{NewColDefinition: yyDollar[3].columnDefinitionUnion(), First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL - case 548: + case 551: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3057 +//line sql.y:3073 { yyLOCAL = &RenameColumn{OldName: yyDollar[3].colNameUnion(), NewName: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL - case 549: + case 552: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3061 +//line sql.y:3077 { yyLOCAL = &AlterCharset{CharacterSet: yyDollar[4].str, Collate: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 550: + case 553: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3065 +//line sql.y:3081 { yyLOCAL = &KeyState{Enable: false} } yyVAL.union = yyLOCAL - case 551: + case 554: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3069 +//line sql.y:3085 { yyLOCAL = &KeyState{Enable: true} } yyVAL.union = yyLOCAL - case 552: + case 555: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3073 +//line sql.y:3089 { yyLOCAL = &TablespaceOperation{Import: false} } yyVAL.union = yyLOCAL - case 553: + case 556: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3077 +//line sql.y:3093 { yyLOCAL = &TablespaceOperation{Import: true} } yyVAL.union = yyLOCAL - case 554: + case 557: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3081 +//line sql.y:3097 { yyLOCAL = &DropColumn{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL - case 555: + case 558: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3085 +//line sql.y:3101 { yyLOCAL = &DropKey{Type: NormalKeyType, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 556: + case 559: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3089 +//line sql.y:3105 { yyLOCAL = &DropKey{Type: PrimaryKeyType} } yyVAL.union = yyLOCAL - case 557: + case 560: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3093 +//line sql.y:3109 { yyLOCAL = &DropKey{Type: ForeignKeyType, Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 558: + case 561: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3097 +//line sql.y:3113 { yyLOCAL = &DropKey{Type: CheckKeyType, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 559: + case 562: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3101 +//line sql.y:3117 { yyLOCAL = &DropKey{Type: CheckKeyType, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 560: + case 563: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3105 +//line sql.y:3121 { yyLOCAL = &Force{} } yyVAL.union = yyLOCAL - case 561: + case 564: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3109 +//line sql.y:3125 { yyLOCAL = &RenameTableName{Table: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 562: + case 565: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3113 +//line sql.y:3129 { yyLOCAL = &RenameIndex{OldName: yyDollar[3].identifierCI, NewName: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 563: + case 566: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:3119 +//line sql.y:3135 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 564: + case 567: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3123 +//line sql.y:3139 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - case 565: + case 568: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3129 +//line sql.y:3145 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } yyVAL.union = yyLOCAL - case 566: + case 569: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3133 +//line sql.y:3149 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } yyVAL.union = yyLOCAL - case 567: + case 570: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3137 +//line sql.y:3153 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } yyVAL.union = yyLOCAL - case 568: + case 571: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3141 +//line sql.y:3157 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } yyVAL.union = yyLOCAL - case 569: + case 572: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3145 +//line sql.y:3161 { yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL - case 570: + case 573: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3149 +//line sql.y:3165 { yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL - case 571: + case 574: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3153 +//line sql.y:3169 { yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL - case 572: + case 575: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3157 +//line sql.y:3173 { yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL - case 573: + case 576: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3161 +//line sql.y:3177 { yyLOCAL = &Validation{With: true} } yyVAL.union = yyLOCAL - case 574: + case 577: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3165 +//line sql.y:3181 { yyLOCAL = &Validation{With: false} } yyVAL.union = yyLOCAL - case 575: + case 578: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3171 +//line sql.y:3187 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -14301,10 +14306,10 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 576: + case 579: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3178 +//line sql.y:3194 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -14312,10 +14317,10 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 577: + case 580: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3185 +//line sql.y:3201 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -14323,28 +14328,28 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 578: + case 581: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:3192 +//line sql.y:3208 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().PartitionSpec = yyDollar[2].partSpecUnion() yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 579: + case 582: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL Statement -//line sql.y:3198 +//line sql.y:3214 { - 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} + 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].tableStmtUnion(), CheckOption: yyDollar[11].str} } yyVAL.union = yyLOCAL - case 580: + case 583: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3208 +//line sql.y:3224 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].identifierCS @@ -14352,10 +14357,10 @@ yydefault: yyLOCAL = yyDollar[1].alterDatabaseUnion() } yyVAL.union = yyLOCAL - case 581: + case 584: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3215 +//line sql.y:3231 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].identifierCS @@ -14363,10 +14368,10 @@ yydefault: yyLOCAL = yyDollar[1].alterDatabaseUnion() } yyVAL.union = yyLOCAL - case 582: + case 585: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:3222 +//line sql.y:3238 { yyLOCAL = &AlterVschema{ Action: CreateVindexDDLAction, @@ -14379,10 +14384,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 583: + case 586: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3234 +//line sql.y:3250 { yyLOCAL = &AlterVschema{ Action: DropVindexDDLAction, @@ -14393,26 +14398,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 584: + case 587: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3244 +//line sql.y:3260 { yyLOCAL = &AlterVschema{Action: AddVschemaTableDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 585: + case 588: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3248 +//line sql.y:3264 { yyLOCAL = &AlterVschema{Action: DropVschemaTableDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 586: + case 589: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL Statement -//line sql.y:3252 +//line sql.y:3268 { yyLOCAL = &AlterVschema{ Action: AddColVindexDDLAction, @@ -14426,10 +14431,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 587: + case 590: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:3265 +//line sql.y:3281 { yyLOCAL = &AlterVschema{ Action: DropColVindexDDLAction, @@ -14440,26 +14445,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 588: + case 591: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3275 +//line sql.y:3291 { yyLOCAL = &AlterVschema{Action: AddSequenceDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 589: + case 592: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3279 +//line sql.y:3295 { yyLOCAL = &AlterVschema{Action: DropSequenceDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 590: + case 593: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Statement -//line sql.y:3283 +//line sql.y:3299 { yyLOCAL = &AlterVschema{ Action: AddAutoIncDDLAction, @@ -14471,10 +14476,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 591: + case 594: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3294 +//line sql.y:3310 { yyLOCAL = &AlterVschema{ Action: DropAutoIncDDLAction, @@ -14482,10 +14487,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 592: + case 595: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3301 +//line sql.y:3317 { yyLOCAL = &AlterMigration{ Type: RetryMigrationType, @@ -14493,10 +14498,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 593: + case 596: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3308 +//line sql.y:3324 { yyLOCAL = &AlterMigration{ Type: CleanupMigrationType, @@ -14504,20 +14509,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 594: + case 597: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3315 +//line sql.y:3331 { yyLOCAL = &AlterMigration{ Type: CleanupAllMigrationType, } } yyVAL.union = yyLOCAL - case 595: + case 598: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3321 +//line sql.y:3337 { yyLOCAL = &AlterMigration{ Type: LaunchMigrationType, @@ -14525,10 +14530,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 596: + case 599: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3328 +//line sql.y:3344 { yyLOCAL = &AlterMigration{ Type: LaunchMigrationType, @@ -14537,20 +14542,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 597: + case 600: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3336 +//line sql.y:3352 { yyLOCAL = &AlterMigration{ Type: LaunchAllMigrationType, } } yyVAL.union = yyLOCAL - case 598: + case 601: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3342 +//line sql.y:3358 { yyLOCAL = &AlterMigration{ Type: CompleteMigrationType, @@ -14558,20 +14563,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 599: + case 602: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3349 +//line sql.y:3365 { yyLOCAL = &AlterMigration{ Type: CompleteAllMigrationType, } } yyVAL.union = yyLOCAL - case 600: + case 603: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3355 +//line sql.y:3371 { yyLOCAL = &AlterMigration{ Type: CancelMigrationType, @@ -14579,20 +14584,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 601: + case 604: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3362 +//line sql.y:3378 { yyLOCAL = &AlterMigration{ Type: CancelAllMigrationType, } } yyVAL.union = yyLOCAL - case 602: + case 605: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3368 +//line sql.y:3384 { yyLOCAL = &AlterMigration{ Type: ThrottleMigrationType, @@ -14602,10 +14607,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 603: + case 606: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3377 +//line sql.y:3393 { yyLOCAL = &AlterMigration{ Type: ThrottleAllMigrationType, @@ -14614,10 +14619,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 604: + case 607: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3385 +//line sql.y:3401 { yyLOCAL = &AlterMigration{ Type: UnthrottleMigrationType, @@ -14625,20 +14630,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 605: + case 608: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3392 +//line sql.y:3408 { yyLOCAL = &AlterMigration{ Type: UnthrottleAllMigrationType, } } yyVAL.union = yyLOCAL - case 606: + case 609: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3398 +//line sql.y:3414 { yyLOCAL = &AlterMigration{ Type: ForceCutOverMigrationType, @@ -14646,20 +14651,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 607: + case 610: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3405 +//line sql.y:3421 { yyLOCAL = &AlterMigration{ Type: ForceCutOverAllMigrationType, } } yyVAL.union = yyLOCAL - case 608: + case 611: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3411 +//line sql.y:3427 { yyLOCAL = &AlterMigration{ Type: SetCutOverThresholdMigrationType, @@ -14668,18 +14673,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 609: + case 612: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3420 +//line sql.y:3436 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 610: + case 613: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3424 +//line sql.y:3440 { yyDollar[3].partitionOptionUnion().Partitions = yyDollar[4].integerUnion() yyDollar[3].partitionOptionUnion().SubPartition = yyDollar[5].subPartitionUnion() @@ -14687,10 +14692,10 @@ yydefault: yyLOCAL = yyDollar[3].partitionOptionUnion() } yyVAL.union = yyLOCAL - case 611: + case 614: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3433 +//line sql.y:3449 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -14699,10 +14704,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 612: + case 615: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3441 +//line sql.y:3457 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -14712,10 +14717,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 613: + case 616: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3450 +//line sql.y:3466 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -14723,10 +14728,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 614: + case 617: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3457 +//line sql.y:3473 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -14734,18 +14739,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 615: + case 618: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3465 +//line sql.y:3481 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 616: + case 619: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3469 +//line sql.y:3485 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -14755,10 +14760,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 617: + case 620: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3478 +//line sql.y:3494 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -14769,678 +14774,678 @@ yydefault: } } yyVAL.union = yyLOCAL - case 618: + case 621: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3489 +//line sql.y:3505 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 619: + case 622: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3493 +//line sql.y:3509 { yyLOCAL = yyDollar[2].partDefsUnion() } yyVAL.union = yyLOCAL - case 620: + case 623: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3498 +//line sql.y:3514 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 621: + case 624: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3502 +//line sql.y:3518 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 622: + case 625: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3507 +//line sql.y:3523 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 623: + case 626: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3511 +//line sql.y:3527 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 624: + case 627: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3517 +//line sql.y:3533 { yyLOCAL = &JSONTableExpr{Expr: yyDollar[3].exprUnion(), Filter: yyDollar[5].exprUnion(), Columns: yyDollar[6].jtColumnListUnion(), Alias: yyDollar[8].identifierCS} } yyVAL.union = yyLOCAL - case 625: + case 628: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3523 +//line sql.y:3539 { yyLOCAL = yyDollar[3].jtColumnListUnion() } yyVAL.union = yyLOCAL - case 626: + case 629: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3529 +//line sql.y:3545 { yyLOCAL = []*JtColumnDefinition{yyDollar[1].jtColumnDefinitionUnion()} } yyVAL.union = yyLOCAL - case 627: + case 630: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3533 +//line sql.y:3549 { yySLICE := (*[]*JtColumnDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].jtColumnDefinitionUnion()) } - case 628: + case 631: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3539 +//line sql.y:3555 { yyLOCAL = &JtColumnDefinition{JtOrdinal: &JtOrdinalColDef{Name: yyDollar[1].identifierCI}} } yyVAL.union = yyLOCAL - case 629: + case 632: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3543 +//line sql.y:3559 { 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()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 630: + case 633: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3549 +//line sql.y:3565 { 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()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 631: + case 634: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3555 +//line sql.y:3571 { 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()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 632: + case 635: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3561 +//line sql.y:3577 { 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()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 633: + case 636: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3567 +//line sql.y:3583 { jtNestedPath := &JtNestedPathColDef{Path: yyDollar[3].exprUnion(), Columns: yyDollar[4].jtColumnListUnion()} yyLOCAL = &JtColumnDefinition{JtNestedPath: jtNestedPath} } yyVAL.union = yyLOCAL - case 634: + case 637: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3573 +//line sql.y:3589 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 635: + case 638: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3577 +//line sql.y:3593 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 636: + case 639: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3581 +//line sql.y:3597 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 637: + case 640: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3585 +//line sql.y:3601 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 638: + case 641: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3591 +//line sql.y:3607 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } yyVAL.union = yyLOCAL - case 639: + case 642: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3597 +//line sql.y:3613 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } yyVAL.union = yyLOCAL - case 640: + case 643: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3603 +//line sql.y:3619 { yyLOCAL = &JtOnResponse{ResponseType: ErrorJSONType} } yyVAL.union = yyLOCAL - case 641: + case 644: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3607 +//line sql.y:3623 { yyLOCAL = &JtOnResponse{ResponseType: NullJSONType} } yyVAL.union = yyLOCAL - case 642: + case 645: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3611 +//line sql.y:3627 { yyLOCAL = &JtOnResponse{ResponseType: DefaultJSONType, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 643: + case 646: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3617 +//line sql.y:3633 { yyLOCAL = RangeType } yyVAL.union = yyLOCAL - case 644: + case 647: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3621 +//line sql.y:3637 { yyLOCAL = ListType } yyVAL.union = yyLOCAL - case 645: + case 648: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3626 +//line sql.y:3642 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 646: + case 649: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:3630 +//line sql.y:3646 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 647: + case 650: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3635 +//line sql.y:3651 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 648: + case 651: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:3639 +//line sql.y:3655 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 649: + case 652: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3645 +//line sql.y:3661 { yyLOCAL = &PartitionSpec{Action: AddAction, Definitions: []*PartitionDefinition{yyDollar[4].partDefUnion()}} } yyVAL.union = yyLOCAL - case 650: + case 653: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3649 +//line sql.y:3665 { yyLOCAL = &PartitionSpec{Action: DropAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 651: + case 654: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3653 +//line sql.y:3669 { yyLOCAL = &PartitionSpec{Action: ReorganizeAction, Names: yyDollar[3].partitionsUnion(), Definitions: yyDollar[6].partDefsUnion()} } yyVAL.union = yyLOCAL - case 652: + case 655: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3657 +//line sql.y:3673 { yyLOCAL = &PartitionSpec{Action: DiscardAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 653: + case 656: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3661 +//line sql.y:3677 { yyLOCAL = &PartitionSpec{Action: DiscardAction, IsAll: true} } yyVAL.union = yyLOCAL - case 654: + case 657: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3665 +//line sql.y:3681 { yyLOCAL = &PartitionSpec{Action: ImportAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 655: + case 658: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3669 +//line sql.y:3685 { yyLOCAL = &PartitionSpec{Action: ImportAction, IsAll: true} } yyVAL.union = yyLOCAL - case 656: + case 659: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3673 +//line sql.y:3689 { yyLOCAL = &PartitionSpec{Action: TruncateAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 657: + case 660: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3677 +//line sql.y:3693 { yyLOCAL = &PartitionSpec{Action: TruncateAction, IsAll: true} } yyVAL.union = yyLOCAL - case 658: + case 661: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3681 +//line sql.y:3697 { yyLOCAL = &PartitionSpec{Action: CoalesceAction, Number: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 659: + case 662: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3685 +//line sql.y:3701 { yyLOCAL = &PartitionSpec{Action: ExchangeAction, Names: Partitions{yyDollar[3].identifierCI}, TableName: yyDollar[6].tableName, WithoutValidation: yyDollar[7].booleanUnion()} } yyVAL.union = yyLOCAL - case 660: + case 663: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3689 +//line sql.y:3705 { yyLOCAL = &PartitionSpec{Action: AnalyzeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 661: + case 664: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3693 +//line sql.y:3709 { yyLOCAL = &PartitionSpec{Action: AnalyzeAction, IsAll: true} } yyVAL.union = yyLOCAL - case 662: + case 665: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3697 +//line sql.y:3713 { yyLOCAL = &PartitionSpec{Action: CheckAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 663: + case 666: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3701 +//line sql.y:3717 { yyLOCAL = &PartitionSpec{Action: CheckAction, IsAll: true} } yyVAL.union = yyLOCAL - case 664: + case 667: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3705 +//line sql.y:3721 { yyLOCAL = &PartitionSpec{Action: OptimizeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 665: + case 668: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3709 +//line sql.y:3725 { yyLOCAL = &PartitionSpec{Action: OptimizeAction, IsAll: true} } yyVAL.union = yyLOCAL - case 666: + case 669: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3713 +//line sql.y:3729 { yyLOCAL = &PartitionSpec{Action: RebuildAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 667: + case 670: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3717 +//line sql.y:3733 { yyLOCAL = &PartitionSpec{Action: RebuildAction, IsAll: true} } yyVAL.union = yyLOCAL - case 668: + case 671: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3721 +//line sql.y:3737 { yyLOCAL = &PartitionSpec{Action: RepairAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 669: + case 672: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3725 +//line sql.y:3741 { yyLOCAL = &PartitionSpec{Action: RepairAction, IsAll: true} } yyVAL.union = yyLOCAL - case 670: + case 673: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3729 +//line sql.y:3745 { yyLOCAL = &PartitionSpec{Action: UpgradeAction} } yyVAL.union = yyLOCAL - case 671: + case 674: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3734 +//line sql.y:3750 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 672: + case 675: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3738 +//line sql.y:3754 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 673: + case 676: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3742 +//line sql.y:3758 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 674: + case 677: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3748 +//line sql.y:3764 { yyLOCAL = []*PartitionDefinition{yyDollar[1].partDefUnion()} } yyVAL.union = yyLOCAL - case 675: + case 678: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3752 +//line sql.y:3768 { yySLICE := (*[]*PartitionDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].partDefUnion()) } - case 676: + case 679: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3758 +//line sql.y:3774 { yyVAL.partDefUnion().Options = yyDollar[2].partitionDefinitionOptionsUnion() } - case 677: + case 680: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3763 +//line sql.y:3779 { yyLOCAL = &PartitionDefinitionOptions{} } yyVAL.union = yyLOCAL - case 678: + case 681: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3767 +//line sql.y:3783 { yyDollar[1].partitionDefinitionOptionsUnion().ValueRange = yyDollar[2].partitionValueRangeUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 679: + case 682: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3772 +//line sql.y:3788 { yyDollar[1].partitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 680: + case 683: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3777 +//line sql.y:3793 { yyDollar[1].partitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 681: + case 684: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3782 +//line sql.y:3798 { yyDollar[1].partitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 682: + case 685: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3787 +//line sql.y:3803 { yyDollar[1].partitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 683: + case 686: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3792 +//line sql.y:3808 { yyDollar[1].partitionDefinitionOptionsUnion().MaxRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 684: + case 687: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3797 +//line sql.y:3813 { yyDollar[1].partitionDefinitionOptionsUnion().MinRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 685: + case 688: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3802 +//line sql.y:3818 { yyDollar[1].partitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 686: + case 689: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3807 +//line sql.y:3823 { yyDollar[1].partitionDefinitionOptionsUnion().SubPartitionDefinitions = yyDollar[2].subPartitionDefinitionsUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 687: + case 690: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:3813 +//line sql.y:3829 { yyLOCAL = yyDollar[2].subPartitionDefinitionsUnion() } yyVAL.union = yyLOCAL - case 688: + case 691: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:3819 +//line sql.y:3835 { yyLOCAL = SubPartitionDefinitions{yyDollar[1].subPartitionDefinitionUnion()} } yyVAL.union = yyLOCAL - case 689: + case 692: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3823 +//line sql.y:3839 { yySLICE := (*SubPartitionDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].subPartitionDefinitionUnion()) } - case 690: + case 693: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SubPartitionDefinition -//line sql.y:3829 +//line sql.y:3845 { yyLOCAL = &SubPartitionDefinition{Name: yyDollar[2].identifierCI, Options: yyDollar[3].subPartitionDefinitionOptionsUnion()} } yyVAL.union = yyLOCAL - case 691: + case 694: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3834 +//line sql.y:3850 { yyLOCAL = &SubPartitionDefinitionOptions{} } yyVAL.union = yyLOCAL - case 692: + case 695: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3838 +//line sql.y:3854 { yyDollar[1].subPartitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 693: + case 696: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3843 +//line sql.y:3859 { yyDollar[1].subPartitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 694: + case 697: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3848 +//line sql.y:3864 { yyDollar[1].subPartitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 695: + case 698: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3853 +//line sql.y:3869 { yyDollar[1].subPartitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 696: + case 699: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3858 +//line sql.y:3874 { yyDollar[1].subPartitionDefinitionOptionsUnion().MaxRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 697: + case 700: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3863 +//line sql.y:3879 { yyDollar[1].subPartitionDefinitionOptionsUnion().MinRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 698: + case 701: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3868 +//line sql.y:3884 { yyDollar[1].subPartitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 699: + case 702: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3875 +//line sql.y:3891 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -15448,10 +15453,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 700: + case 703: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3882 +//line sql.y:3898 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -15459,10 +15464,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 701: + case 704: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3889 +//line sql.y:3905 { yyLOCAL = &PartitionValueRange{ Type: InType, @@ -15470,131 +15475,131 @@ yydefault: } } yyVAL.union = yyLOCAL - case 702: + case 705: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3897 +//line sql.y:3913 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 703: + case 706: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3901 +//line sql.y:3917 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 704: + case 707: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionEngine -//line sql.y:3907 +//line sql.y:3923 { yyLOCAL = &PartitionEngine{Storage: yyDollar[1].booleanUnion(), Name: yyDollar[4].identifierCS.String()} } yyVAL.union = yyLOCAL - case 705: + case 708: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Literal -//line sql.y:3913 +//line sql.y:3929 { yyLOCAL = NewStrLiteral(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 706: + case 709: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:3919 +//line sql.y:3935 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 707: + case 710: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:3925 +//line sql.y:3941 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 708: + case 711: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3931 +//line sql.y:3947 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 709: + case 712: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3937 +//line sql.y:3953 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 710: + case 713: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3943 +//line sql.y:3959 { yyVAL.str = yyDollar[3].identifierCS.String() } - case 711: + case 714: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinition -//line sql.y:3949 +//line sql.y:3965 { yyLOCAL = &PartitionDefinition{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 712: + case 715: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3955 +//line sql.y:3971 { yyVAL.str = "" } - case 713: + case 716: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3959 +//line sql.y:3975 { yyVAL.str = "" } - case 714: + case 717: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3965 +//line sql.y:3981 { yyLOCAL = &RenameTable{TablePairs: yyDollar[3].renameTablePairsUnion()} } yyVAL.union = yyLOCAL - case 715: + case 718: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*RenameTablePair -//line sql.y:3971 +//line sql.y:3987 { yyLOCAL = []*RenameTablePair{{FromTable: yyDollar[1].tableName, ToTable: yyDollar[3].tableName}} } yyVAL.union = yyLOCAL - case 716: + case 719: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3975 +//line sql.y:3991 { yySLICE := (*[]*RenameTablePair)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &RenameTablePair{FromTable: yyDollar[3].tableName, ToTable: yyDollar[5].tableName}) } - case 717: + case 720: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3981 +//line sql.y:3997 { yyLOCAL = &DropTable{FromTables: yyDollar[6].tableNamesUnion(), IfExists: yyDollar[5].booleanUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), Temp: yyDollar[3].booleanUnion()} } yyVAL.union = yyLOCAL - case 718: + case 721: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3985 +//line sql.y:4001 { // Change this to an alter statement if yyDollar[4].identifierCI.Lowered() == "primary" { @@ -15604,1377 +15609,1377 @@ yydefault: } } yyVAL.union = yyLOCAL - case 719: + case 722: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3994 +//line sql.y:4010 { yyLOCAL = &DropView{FromTables: yyDollar[5].tableNamesUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 720: + case 723: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3998 +//line sql.y:4014 { yyLOCAL = &DropDatabase{Comments: Comments(yyDollar[2].strs).Parsed(), DBName: yyDollar[5].identifierCS, IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 721: + case 724: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4004 +//line sql.y:4020 { yyLOCAL = &TruncateTable{Table: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 722: + case 725: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4008 +//line sql.y:4024 { yyLOCAL = &TruncateTable{Table: yyDollar[2].tableName} } yyVAL.union = yyLOCAL - case 723: + case 726: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4014 +//line sql.y:4030 { yyLOCAL = &Analyze{IsLocal: yyDollar[2].booleanUnion(), Table: yyDollar[4].tableName} } yyVAL.union = yyLOCAL - case 724: + case 727: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4020 +//line sql.y:4036 { yyLOCAL = &PurgeBinaryLogs{To: string(yyDollar[5].str)} } yyVAL.union = yyLOCAL - case 725: + case 728: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4024 +//line sql.y:4040 { yyLOCAL = &PurgeBinaryLogs{Before: string(yyDollar[5].str)} } yyVAL.union = yyLOCAL - case 726: + case 729: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4030 +//line sql.y:4046 { yyLOCAL = &Show{&ShowBasic{Command: Charset, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 727: + case 730: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4034 +//line sql.y:4050 { yyLOCAL = &Show{&ShowBasic{Command: Collation, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 728: + case 731: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4038 +//line sql.y:4054 { yyLOCAL = &Show{&ShowBasic{Full: yyDollar[2].booleanUnion(), Command: Column, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 729: + case 732: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4042 +//line sql.y:4058 { yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 730: + case 733: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4046 +//line sql.y:4062 { yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 731: + case 734: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4050 +//line sql.y:4066 { yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 732: + case 735: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4054 +//line sql.y:4070 { yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 733: + case 736: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4058 +//line sql.y:4074 { yyLOCAL = &Show{&ShowBasic{Command: Function, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 734: + case 737: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4062 +//line sql.y:4078 { yyLOCAL = &Show{&ShowBasic{Command: Index, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 735: + case 738: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4066 +//line sql.y:4082 { yyLOCAL = &Show{&ShowBasic{Command: OpenTable, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 736: + case 739: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4070 +//line sql.y:4086 { yyLOCAL = &Show{&ShowBasic{Command: Privilege}} } yyVAL.union = yyLOCAL - case 737: + case 740: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4074 +//line sql.y:4090 { yyLOCAL = &Show{&ShowBasic{Command: Procedure, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 738: + case 741: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4078 +//line sql.y:4094 { yyLOCAL = &Show{&ShowBasic{Command: StatusSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 739: + case 742: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4082 +//line sql.y:4098 { yyLOCAL = &Show{&ShowBasic{Command: StatusGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 740: + case 743: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4086 +//line sql.y:4102 { yyLOCAL = &Show{&ShowBasic{Command: VariableSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 741: + case 744: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4090 +//line sql.y:4106 { yyLOCAL = &Show{&ShowBasic{Command: VariableGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 742: + case 745: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4094 +//line sql.y:4110 { yyLOCAL = &Show{&ShowBasic{Command: TableStatus, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 743: + case 746: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4098 +//line sql.y:4114 { yyLOCAL = &Show{&ShowBasic{Command: Table, Full: yyDollar[2].booleanUnion(), DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 744: + case 747: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4102 +//line sql.y:4118 { yyLOCAL = &Show{&ShowBasic{Command: Trigger, DbName: yyDollar[3].identifierCS, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 745: + case 748: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4106 +//line sql.y:4122 { yyLOCAL = &Show{&ShowCreate{Command: CreateDb, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 746: + case 749: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4110 +//line sql.y:4126 { yyLOCAL = &Show{&ShowCreate{Command: CreateE, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 747: + case 750: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4114 +//line sql.y:4130 { yyLOCAL = &Show{&ShowCreate{Command: CreateF, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 748: + case 751: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4118 +//line sql.y:4134 { yyLOCAL = &Show{&ShowCreate{Command: CreateProc, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 749: + case 752: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4122 +//line sql.y:4138 { yyLOCAL = &Show{&ShowCreate{Command: CreateTbl, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 750: + case 753: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4126 +//line sql.y:4142 { yyLOCAL = &Show{&ShowCreate{Command: CreateTr, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 751: + case 754: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4130 +//line sql.y:4146 { yyLOCAL = &Show{&ShowCreate{Command: CreateV, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 752: + case 755: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4134 +//line sql.y:4150 { yyLOCAL = &Show{&ShowBasic{Command: Engines}} } yyVAL.union = yyLOCAL - case 753: + case 756: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4138 +//line sql.y:4154 { yyLOCAL = &Show{&ShowBasic{Command: Plugins}} } yyVAL.union = yyLOCAL - case 754: + case 757: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4142 +//line sql.y:4158 { yyLOCAL = &Show{&ShowBasic{Command: GtidExecGlobal, DbName: yyDollar[4].identifierCS}} } yyVAL.union = yyLOCAL - case 755: + case 758: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4146 +//line sql.y:4162 { yyLOCAL = &Show{&ShowBasic{Command: VGtidExecGlobal, DbName: yyDollar[4].identifierCS}} } yyVAL.union = yyLOCAL - case 756: + case 759: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4150 +//line sql.y:4166 { yyLOCAL = &Show{&ShowBasic{Command: VitessVariables, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 757: + case 760: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4154 +//line sql.y:4170 { yyLOCAL = &Show{&ShowBasic{Command: VitessMigrations, Filter: yyDollar[4].showFilterUnion(), DbName: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL - case 758: + case 761: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4158 +//line sql.y:4174 { yyLOCAL = &ShowMigrationLogs{UUID: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 759: + case 762: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4162 +//line sql.y:4178 { yyLOCAL = &ShowThrottledApps{} } yyVAL.union = yyLOCAL - case 760: + case 763: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4166 +//line sql.y:4182 { yyLOCAL = &Show{&ShowBasic{Command: VitessReplicationStatus, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 761: + case 764: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4170 +//line sql.y:4186 { yyLOCAL = &ShowThrottlerStatus{} } yyVAL.union = yyLOCAL - case 762: + case 765: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4174 +//line sql.y:4190 { yyLOCAL = &Show{&ShowBasic{Command: VschemaTables}} } yyVAL.union = yyLOCAL - case 763: + case 766: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4178 +//line sql.y:4194 { yyLOCAL = &Show{&ShowBasic{Command: VschemaKeyspaces}} } yyVAL.union = yyLOCAL - case 764: + case 767: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4182 +//line sql.y:4198 { yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes}} } yyVAL.union = yyLOCAL - case 765: + case 768: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4186 +//line sql.y:4202 { yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes, Tbl: yyDollar[5].tableName}} } yyVAL.union = yyLOCAL - case 766: + case 769: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4190 +//line sql.y:4206 { yyLOCAL = &Show{&ShowBasic{Command: Warnings}} } yyVAL.union = yyLOCAL - case 767: + case 770: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4194 +//line sql.y:4210 { yyLOCAL = &Show{&ShowBasic{Command: VitessShards, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 768: + case 771: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4198 +//line sql.y:4214 { yyLOCAL = &Show{&ShowBasic{Command: VitessTablets, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 769: + case 772: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4202 +//line sql.y:4218 { yyLOCAL = &Show{&ShowBasic{Command: VitessTarget}} } yyVAL.union = yyLOCAL - case 770: + case 773: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4209 +//line sql.y:4225 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].identifierCI.String())}} } yyVAL.union = yyLOCAL - case 771: + case 774: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4213 +//line sql.y:4229 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL - case 772: + case 775: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4217 +//line sql.y:4233 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String()}} } yyVAL.union = yyLOCAL - case 773: + case 776: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4221 +//line sql.y:4237 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL - case 774: + case 777: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4225 +//line sql.y:4241 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL - case 775: + case 778: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4229 +//line sql.y:4245 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } yyVAL.union = yyLOCAL - case 776: + case 779: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4233 +//line sql.y:4249 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } yyVAL.union = yyLOCAL - case 777: + case 780: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4237 +//line sql.y:4253 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL - case 778: + case 781: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4241 +//line sql.y:4257 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL - case 779: + case 782: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4245 +//line sql.y:4261 { yyLOCAL = &Show{&ShowTransactionStatus{TransactionID: string(yyDollar[5].str)}} } yyVAL.union = yyLOCAL - case 780: + case 783: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4249 +//line sql.y:4265 { yyLOCAL = &Show{&ShowTransactionStatus{}} } yyVAL.union = yyLOCAL - case 781: + case 784: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4253 +//line sql.y:4269 { yyLOCAL = &Show{&ShowTransactionStatus{Keyspace: yyDollar[5].identifierCS.String()}} } yyVAL.union = yyLOCAL - case 782: + case 785: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4258 +//line sql.y:4274 { } - case 783: + case 786: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4260 +//line sql.y:4276 { } - case 784: + case 787: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4264 +//line sql.y:4280 { yyVAL.str = "" } - case 785: + case 788: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4268 +//line sql.y:4284 { yyVAL.str = "extended " } - case 786: + case 789: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4274 +//line sql.y:4290 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 787: + case 790: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4278 +//line sql.y:4294 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 788: + case 791: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4284 +//line sql.y:4300 { yyVAL.str = string(yyDollar[1].str) } - case 789: + case 792: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4288 +//line sql.y:4304 { yyVAL.str = string(yyDollar[1].str) } - case 790: + case 793: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4294 +//line sql.y:4310 { yyVAL.identifierCS = NewIdentifierCS("") } - case 791: + case 794: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4298 +//line sql.y:4314 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 792: + case 795: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4302 +//line sql.y:4318 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 793: + case 796: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4308 +//line sql.y:4324 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 794: + case 797: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4312 +//line sql.y:4328 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 795: + case 798: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4316 +//line sql.y:4332 { yyLOCAL = &ShowFilter{Filter: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 796: + case 799: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4322 +//line sql.y:4338 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 797: + case 800: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4326 +//line sql.y:4342 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 798: + case 801: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4332 +//line sql.y:4348 { yyVAL.empty = struct{}{} } - case 799: + case 802: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4336 +//line sql.y:4352 { yyVAL.empty = struct{}{} } - case 800: + case 803: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4340 +//line sql.y:4356 { yyVAL.empty = struct{}{} } - case 801: + case 804: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4346 +//line sql.y:4362 { yyVAL.str = string(yyDollar[1].str) } - case 802: + case 805: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4350 +//line sql.y:4366 { yyVAL.str = string(yyDollar[1].str) } - case 803: + case 806: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4356 +//line sql.y:4372 { yyLOCAL = &Use{DBName: yyDollar[2].identifierCS} } yyVAL.union = yyLOCAL - case 804: + case 807: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4360 +//line sql.y:4376 { yyLOCAL = &Use{DBName: IdentifierCS{v: ""}} } yyVAL.union = yyLOCAL - case 805: + case 808: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4364 +//line sql.y:4380 { yyLOCAL = &Use{DBName: NewIdentifierCS(yyDollar[2].identifierCS.String() + "@" + string(yyDollar[3].str))} } yyVAL.union = yyLOCAL - case 806: + case 809: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4371 +//line sql.y:4387 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 807: + case 810: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4375 +//line sql.y:4391 { yyVAL.identifierCS = NewIdentifierCS("@" + string(yyDollar[1].str)) } - case 808: + case 811: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4379 +//line sql.y:4395 { yyVAL.identifierCS = NewIdentifierCS("@@" + string(yyDollar[1].str)) } - case 809: + case 812: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4383 +//line sql.y:4399 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 810: + case 813: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4390 +//line sql.y:4406 { yyLOCAL = &Begin{} } yyVAL.union = yyLOCAL - case 811: + case 814: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4394 +//line sql.y:4410 { yyLOCAL = &Begin{TxAccessModes: yyDollar[3].txAccessModesUnion()} } yyVAL.union = yyLOCAL - case 812: + case 815: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4399 +//line sql.y:4415 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 813: + case 816: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4403 +//line sql.y:4419 { yyLOCAL = yyDollar[1].txAccessModesUnion() } yyVAL.union = yyLOCAL - case 814: + case 817: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4409 +//line sql.y:4425 { yyLOCAL = []TxAccessMode{yyDollar[1].txAccessModeUnion()} } yyVAL.union = yyLOCAL - case 815: + case 818: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4413 +//line sql.y:4429 { yySLICE := (*[]TxAccessMode)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].txAccessModeUnion()) } - case 816: + case 819: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4419 +//line sql.y:4435 { yyLOCAL = WithConsistentSnapshot } yyVAL.union = yyLOCAL - case 817: + case 820: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4423 +//line sql.y:4439 { yyLOCAL = ReadWrite } yyVAL.union = yyLOCAL - case 818: + case 821: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4427 +//line sql.y:4443 { yyLOCAL = ReadOnly } yyVAL.union = yyLOCAL - case 819: + case 822: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4434 +//line sql.y:4450 { yyLOCAL = &Commit{} } yyVAL.union = yyLOCAL - case 820: + case 823: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4440 +//line sql.y:4456 { yyLOCAL = &Rollback{} } yyVAL.union = yyLOCAL - case 821: + case 824: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4444 +//line sql.y:4460 { yyLOCAL = &SRollback{Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 822: + case 825: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4449 +//line sql.y:4465 { yyVAL.empty = struct{}{} } - case 823: + case 826: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4451 +//line sql.y:4467 { yyVAL.empty = struct{}{} } - case 824: + case 827: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4454 +//line sql.y:4470 { yyVAL.empty = struct{}{} } - case 825: + case 828: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4456 +//line sql.y:4472 { yyVAL.empty = struct{}{} } - case 826: + case 829: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4460 +//line sql.y:4476 { yyLOCAL = &Savepoint{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 827: + case 830: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4466 +//line sql.y:4482 { yyLOCAL = &Release{Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 828: + case 831: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4471 +//line sql.y:4487 { yyLOCAL = EmptyType } yyVAL.union = yyLOCAL - case 829: + case 832: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4475 +//line sql.y:4491 { yyLOCAL = JSONType } yyVAL.union = yyLOCAL - case 830: + case 833: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4479 +//line sql.y:4495 { yyLOCAL = TreeType } yyVAL.union = yyLOCAL - case 831: + case 834: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4483 +//line sql.y:4499 { yyLOCAL = TraditionalType } yyVAL.union = yyLOCAL - case 832: + case 835: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4487 +//line sql.y:4503 { yyLOCAL = AnalyzeType } yyVAL.union = yyLOCAL - case 833: + case 836: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4492 +//line sql.y:4508 { yyLOCAL = PlanVExplainType } yyVAL.union = yyLOCAL - case 834: + case 837: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4496 +//line sql.y:4512 { yyLOCAL = PlanVExplainType } yyVAL.union = yyLOCAL - case 835: + case 838: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4500 +//line sql.y:4516 { yyLOCAL = AllVExplainType } yyVAL.union = yyLOCAL - case 836: + case 839: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4504 +//line sql.y:4520 { yyLOCAL = QueriesVExplainType } yyVAL.union = yyLOCAL - case 837: + case 840: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4508 +//line sql.y:4524 { yyLOCAL = TraceVExplainType } yyVAL.union = yyLOCAL - case 838: + case 841: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4512 +//line sql.y:4528 { yyLOCAL = KeysVExplainType } yyVAL.union = yyLOCAL - case 839: + case 842: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4518 +//line sql.y:4534 { yyVAL.str = yyDollar[1].str } - case 840: + case 843: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4522 +//line sql.y:4538 { yyVAL.str = yyDollar[1].str } - case 841: + case 844: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4526 +//line sql.y:4542 { yyVAL.str = yyDollar[1].str } - case 842: + case 845: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4532 +//line sql.y:4548 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL - case 843: + case 846: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4536 +//line sql.y:4552 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 844: + case 847: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4540 +//line sql.y:4556 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 845: + case 848: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4544 +//line sql.y:4560 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 846: + case 849: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4549 +//line sql.y:4565 { yyVAL.str = "" } - case 847: + case 850: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4553 +//line sql.y:4569 { yyVAL.str = yyDollar[1].identifierCI.val } - case 848: + case 851: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4557 +//line sql.y:4573 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 849: + case 852: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4563 +//line sql.y:4579 { yyLOCAL = &ExplainTab{Table: yyDollar[3].tableName, Wild: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 850: + case 853: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4567 +//line sql.y:4583 { yyLOCAL = &ExplainStmt{Type: yyDollar[3].explainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 851: + case 854: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4573 +//line sql.y:4589 { yyLOCAL = &VExplainStmt{Type: yyDollar[3].vexplainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 852: + case 855: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4579 +//line sql.y:4595 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 853: + case 856: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4583 +//line sql.y:4599 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 854: + case 857: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4589 +//line sql.y:4605 { yyLOCAL = &LockTables{Tables: yyDollar[3].tableAndLockTypesUnion()} } yyVAL.union = yyLOCAL - case 855: + case 858: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableAndLockTypes -//line sql.y:4595 +//line sql.y:4611 { yyLOCAL = TableAndLockTypes{yyDollar[1].tableAndLockTypeUnion()} } yyVAL.union = yyLOCAL - case 856: + case 859: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4599 +//line sql.y:4615 { yySLICE := (*TableAndLockTypes)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableAndLockTypeUnion()) } - case 857: + case 860: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *TableAndLockType -//line sql.y:4605 +//line sql.y:4621 { yyLOCAL = &TableAndLockType{Table: yyDollar[1].aliasedTableNameUnion(), Lock: yyDollar[2].lockTypeUnion()} } yyVAL.union = yyLOCAL - case 858: + case 861: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4611 +//line sql.y:4627 { yyLOCAL = Read } yyVAL.union = yyLOCAL - case 859: + case 862: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4615 +//line sql.y:4631 { yyLOCAL = ReadLocal } yyVAL.union = yyLOCAL - case 860: + case 863: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4619 +//line sql.y:4635 { yyLOCAL = Write } yyVAL.union = yyLOCAL - case 861: + case 864: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4623 +//line sql.y:4639 { yyLOCAL = LowPriorityWrite } yyVAL.union = yyLOCAL - case 862: + case 865: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4629 +//line sql.y:4645 { yyLOCAL = &UnlockTables{} } yyVAL.union = yyLOCAL - case 863: + case 866: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4635 +//line sql.y:4651 { yyLOCAL = &RevertMigration{Comments: Comments(yyDollar[2].strs).Parsed(), UUID: string(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 864: + case 867: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4641 +//line sql.y:4657 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), FlushOptions: yyDollar[3].strs} } yyVAL.union = yyLOCAL - case 865: + case 868: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4645 +//line sql.y:4661 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion()} } yyVAL.union = yyLOCAL - case 866: + case 869: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4649 +//line sql.y:4665 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 867: + case 870: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4653 +//line sql.y:4669 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL - case 868: + case 871: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4657 +//line sql.y:4673 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 869: + case 872: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4661 +//line sql.y:4677 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), ForExport: true} } yyVAL.union = yyLOCAL - case 870: + case 873: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4667 +//line sql.y:4683 { yyVAL.strs = []string{yyDollar[1].str} } - case 871: + case 874: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4671 +//line sql.y:4687 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) } - case 872: + case 875: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4677 +//line sql.y:4693 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 873: + case 876: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4681 +//line sql.y:4697 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 874: + case 877: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4685 +//line sql.y:4701 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 875: + case 878: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4689 +//line sql.y:4705 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 876: + case 879: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4693 +//line sql.y:4709 { yyVAL.str = string(yyDollar[1].str) } - case 877: + case 880: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4697 +//line sql.y:4713 { yyVAL.str = string(yyDollar[1].str) } - case 878: + case 881: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4701 +//line sql.y:4717 { yyVAL.str = string(yyDollar[1].str) } - case 879: + case 882: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4705 +//line sql.y:4721 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str } - case 880: + case 883: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4709 +//line sql.y:4725 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 881: + case 884: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4713 +//line sql.y:4729 { yyVAL.str = string(yyDollar[1].str) } - case 882: + case 885: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4717 +//line sql.y:4733 { yyVAL.str = string(yyDollar[1].str) } - case 883: + case 886: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4721 +//line sql.y:4737 { yyVAL.str = string(yyDollar[1].str) } - case 884: + case 887: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4726 +//line sql.y:4742 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 885: + case 888: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4730 +//line sql.y:4746 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 886: + case 889: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4734 +//line sql.y:4750 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 887: + case 890: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4739 +//line sql.y:4755 { yyVAL.str = "" } - case 888: + case 891: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4743 +//line sql.y:4759 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String() } - case 889: + case 892: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4748 +//line sql.y:4764 { setAllowComments(yylex, true) } - case 890: + case 893: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4752 +//line sql.y:4768 { yyVAL.strs = yyDollar[2].strs setAllowComments(yylex, false) } - case 891: + case 894: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4758 +//line sql.y:4774 { yyVAL.strs = nil } - case 892: + case 895: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4762 +//line sql.y:4778 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } - case 893: + case 896: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4768 +//line sql.y:4784 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 894: + case 897: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4772 +//line sql.y:4788 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 895: + case 898: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4776 +//line sql.y:4792 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 896: + case 899: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4781 +//line sql.y:4797 { yyVAL.str = "" } - case 897: + case 900: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4785 +//line sql.y:4801 { yyVAL.str = SQLNoCacheStr } - case 898: + case 901: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4789 +//line sql.y:4805 { yyVAL.str = SQLCacheStr } - case 899: + case 902: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4794 +//line sql.y:4810 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 900: + case 903: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4798 +//line sql.y:4814 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 901: + case 904: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4802 +//line sql.y:4818 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 902: + case 905: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4808 +//line sql.y:4824 { yyLOCAL = &PrepareStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Statement: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 903: + case 906: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4812 +//line sql.y:4828 { yyLOCAL = &PrepareStmt{ Name: yyDollar[3].identifierCI, @@ -16983,597 +16988,597 @@ yydefault: } } yyVAL.union = yyLOCAL - case 904: + case 907: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4822 +//line sql.y:4838 { yyLOCAL = &ExecuteStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Arguments: yyDollar[4].variablesUnion()} } yyVAL.union = yyLOCAL - case 905: + case 908: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4827 +//line sql.y:4843 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 906: + case 909: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4831 +//line sql.y:4847 { yyLOCAL = yyDollar[2].variablesUnion() } yyVAL.union = yyLOCAL - case 907: + case 910: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4837 +//line sql.y:4853 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 908: + case 911: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4841 +//line sql.y:4857 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 909: + case 912: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4846 +//line sql.y:4862 { yyVAL.strs = nil } - case 910: + case 913: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4850 +//line sql.y:4866 { yyVAL.strs = yyDollar[1].strs } - case 911: + case 914: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4856 +//line sql.y:4872 { yyVAL.strs = []string{yyDollar[1].str} } - case 912: + case 915: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4860 +//line sql.y:4876 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } - case 913: + case 916: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4866 +//line sql.y:4882 { yyVAL.str = SQLNoCacheStr } - case 914: + case 917: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4870 +//line sql.y:4886 { yyVAL.str = SQLCacheStr } - case 915: + case 918: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4874 +//line sql.y:4890 { yyVAL.str = DistinctStr } - case 916: + case 919: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4878 +//line sql.y:4894 { yyVAL.str = DistinctStr } - case 917: + case 920: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4882 +//line sql.y:4898 { yyVAL.str = HighPriorityStr } - case 918: + case 921: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4886 +//line sql.y:4902 { yyVAL.str = StraightJoinHint } - case 919: + case 922: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4890 +//line sql.y:4906 { yyVAL.str = SQLBufferResultStr } - case 920: + case 923: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4894 +//line sql.y:4910 { yyVAL.str = SQLSmallResultStr } - case 921: + case 924: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4898 +//line sql.y:4914 { yyVAL.str = SQLBigResultStr } - case 922: + case 925: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4902 +//line sql.y:4918 { yyVAL.str = SQLCalcFoundRowsStr } - case 923: + case 926: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4906 +//line sql.y:4922 { 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 924: + case 927: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4912 +//line sql.y:4928 { yyLOCAL = SelectExprs{yyDollar[1].selectExprUnion()} } yyVAL.union = yyLOCAL - case 925: + case 928: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4916 +//line sql.y:4932 { yySLICE := (*SelectExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].selectExprUnion()) } - case 926: + case 929: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4922 +//line sql.y:4938 { yyLOCAL = &StarExpr{} } yyVAL.union = yyLOCAL - case 927: + case 930: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4926 +//line sql.y:4942 { yyLOCAL = &AliasedExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 928: + case 931: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4930 +//line sql.y:4946 { yyLOCAL = &StarExpr{TableName: TableName{Name: yyDollar[1].identifierCS}} } yyVAL.union = yyLOCAL - case 929: + case 932: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4934 +//line sql.y:4950 { yyLOCAL = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL - case 930: + case 933: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4939 +//line sql.y:4955 { yyVAL.identifierCI = IdentifierCI{} } - case 931: + case 934: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4943 +//line sql.y:4959 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 932: + case 935: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4947 +//line sql.y:4963 { yyVAL.identifierCI = yyDollar[2].identifierCI } - case 934: + case 937: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4954 +//line sql.y:4970 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 935: + case 938: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4959 +//line sql.y:4975 { yyLOCAL = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewIdentifierCS("dual")}}} } yyVAL.union = yyLOCAL - case 936: + case 939: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4963 +//line sql.y:4979 { yyLOCAL = yyDollar[1].tableExprsUnion() } yyVAL.union = yyLOCAL - case 937: + case 940: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4969 +//line sql.y:4985 { yyLOCAL = yyDollar[2].tableExprsUnion() } yyVAL.union = yyLOCAL - case 938: + case 941: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4975 +//line sql.y:4991 { yyLOCAL = TableExprs{yyDollar[1].tableExprUnion()} } yyVAL.union = yyLOCAL - case 939: + case 942: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4979 +//line sql.y:4995 { yySLICE := (*TableExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableExprUnion()) } - case 942: + case 945: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4989 +//line sql.y:5005 { yyLOCAL = yyDollar[1].aliasedTableNameUnion() } yyVAL.union = yyLOCAL - case 943: + case 946: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4993 +//line sql.y:5009 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].derivedTableUnion(), As: yyDollar[3].identifierCS, Columns: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 944: + case 947: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4997 +//line sql.y:5013 { yyLOCAL = &ParenTableExpr{Exprs: yyDollar[2].tableExprsUnion()} } yyVAL.union = yyLOCAL - case 945: + case 948: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5001 +//line sql.y:5017 { yyLOCAL = yyDollar[1].tableExprUnion() } yyVAL.union = yyLOCAL - case 946: + case 949: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:5007 +//line sql.y:5023 { - yyLOCAL = &DerivedTable{Lateral: false, Select: yyDollar[1].selStmtUnion()} + yyLOCAL = &DerivedTable{Lateral: false, Select: yyDollar[1].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 947: + case 950: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:5011 +//line sql.y:5027 { - yyLOCAL = &DerivedTable{Lateral: true, Select: yyDollar[2].selStmtUnion()} + yyLOCAL = &DerivedTable{Lateral: true, Select: yyDollar[2].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 948: + case 951: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:5017 +//line sql.y:5033 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].identifierCS, Hints: yyDollar[3].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 949: + case 952: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:5021 +//line sql.y:5037 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitionsUnion(), As: yyDollar[6].identifierCS, Hints: yyDollar[7].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 950: + case 953: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:5026 +//line sql.y:5042 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 951: + case 954: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:5030 +//line sql.y:5046 { yyLOCAL = yyDollar[2].columnsUnion() } yyVAL.union = yyLOCAL - case 952: + case 955: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:5035 +//line sql.y:5051 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 953: + case 956: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5039 +//line sql.y:5055 { yyLOCAL = yyDollar[1].columnsUnion() } yyVAL.union = yyLOCAL - case 954: + case 957: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5045 +//line sql.y:5061 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 955: + case 958: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5049 +//line sql.y:5065 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 956: + case 959: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:5055 +//line sql.y:5071 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } yyVAL.union = yyLOCAL - case 957: + case 960: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5059 +//line sql.y:5075 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) } - case 958: + case 961: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5065 +//line sql.y:5081 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 959: + case 962: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5069 +//line sql.y:5085 { yyLOCAL = Columns{NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 960: + case 963: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5073 +//line sql.y:5089 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 961: + case 964: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5077 +//line sql.y:5093 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, NewIdentifierCI(string(yyDollar[3].str))) } - case 962: + case 965: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Partitions -//line sql.y:5083 +//line sql.y:5099 { yyLOCAL = Partitions{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 963: + case 966: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5087 +//line sql.y:5103 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 964: + case 967: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5100 +//line sql.y:5116 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 965: + case 968: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5104 +//line sql.y:5120 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 966: + case 969: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5108 +//line sql.y:5124 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 967: + case 970: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5112 +//line sql.y:5128 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL - case 968: + case 971: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5118 +//line sql.y:5134 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 969: + case 972: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:5120 +//line sql.y:5136 { yyVAL.joinCondition = &JoinCondition{Using: yyDollar[3].columnsUnion()} } - case 970: + case 973: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5124 +//line sql.y:5140 { yyVAL.joinCondition = &JoinCondition{} } - case 971: + case 974: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5126 +//line sql.y:5142 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 972: + case 975: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5130 +//line sql.y:5146 { yyVAL.joinCondition = &JoinCondition{} } - case 973: + case 976: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5132 +//line sql.y:5148 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 974: + case 977: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5135 +//line sql.y:5151 { yyVAL.empty = struct{}{} } - case 975: + case 978: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5137 +//line sql.y:5153 { yyVAL.empty = struct{}{} } - case 976: + case 979: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5140 +//line sql.y:5156 { yyVAL.identifierCS = NewIdentifierCS("") } - case 977: + case 980: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5144 +//line sql.y:5160 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 978: + case 981: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5148 +//line sql.y:5164 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 980: + case 983: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5155 +//line sql.y:5171 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 981: + case 984: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5161 +//line sql.y:5177 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 982: + case 985: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5165 +//line sql.y:5181 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 983: + case 986: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5169 +//line sql.y:5185 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 984: + case 987: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5175 +//line sql.y:5191 { yyLOCAL = StraightJoinType } yyVAL.union = yyLOCAL - case 985: + case 988: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5181 +//line sql.y:5197 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 986: + case 989: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5185 +//line sql.y:5201 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 987: + case 990: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5189 +//line sql.y:5205 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 988: + case 991: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5193 +//line sql.y:5209 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 989: + case 992: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5199 +//line sql.y:5215 { yyLOCAL = NaturalJoinType } yyVAL.union = yyLOCAL - case 990: + case 993: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5203 +//line sql.y:5219 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -17582,667 +17587,667 @@ yydefault: } } yyVAL.union = yyLOCAL - case 991: + case 994: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5213 +//line sql.y:5229 { yyVAL.tableName = yyDollar[2].tableName } - case 992: + case 995: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5217 +//line sql.y:5233 { yyVAL.tableName = yyDollar[1].tableName } - case 993: + case 996: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5223 +//line sql.y:5239 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 994: + case 997: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5227 +//line sql.y:5243 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS} } - case 995: + case 998: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5233 +//line sql.y:5249 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 996: + case 999: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5238 +//line sql.y:5254 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 997: + case 1000: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5242 +//line sql.y:5258 { yyLOCAL = yyDollar[1].indexHintsUnion() } yyVAL.union = yyLOCAL - case 998: + case 1001: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5248 +//line sql.y:5264 { yyLOCAL = IndexHints{yyDollar[1].indexHintUnion()} } yyVAL.union = yyLOCAL - case 999: + case 1002: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5252 +//line sql.y:5268 { yySLICE := (*IndexHints)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexHintUnion()) } - case 1000: + case 1003: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5258 +//line sql.y:5274 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 1001: + case 1004: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5262 +//line sql.y:5278 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion()} } yyVAL.union = yyLOCAL - case 1002: + case 1005: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5266 +//line sql.y:5282 { yyLOCAL = &IndexHint{Type: IgnoreOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 1003: + case 1006: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5270 +//line sql.y:5286 { yyLOCAL = &IndexHint{Type: ForceOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 1004: + case 1007: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5274 +//line sql.y:5290 { yyLOCAL = &IndexHint{Type: UseVindexOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1005: + case 1008: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5278 +//line sql.y:5294 { yyLOCAL = &IndexHint{Type: IgnoreVindexOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1006: + case 1009: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5283 +//line sql.y:5299 { yyLOCAL = NoForType } yyVAL.union = yyLOCAL - case 1007: + case 1010: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5287 +//line sql.y:5303 { yyLOCAL = JoinForType } yyVAL.union = yyLOCAL - case 1008: + case 1011: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5291 +//line sql.y:5307 { yyLOCAL = OrderByForType } yyVAL.union = yyLOCAL - case 1009: + case 1012: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5295 +//line sql.y:5311 { yyLOCAL = GroupByForType } yyVAL.union = yyLOCAL - case 1010: + case 1013: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:5301 +//line sql.y:5317 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1011: + case 1014: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5305 +//line sql.y:5321 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1012: + case 1015: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5312 +//line sql.y:5328 { yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1013: + case 1016: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5316 +//line sql.y:5332 { yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1014: + case 1017: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5320 +//line sql.y:5336 { yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1015: + case 1018: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5324 +//line sql.y:5340 { yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1016: + case 1019: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5328 +//line sql.y:5344 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} } yyVAL.union = yyLOCAL - case 1017: + case 1020: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5332 +//line sql.y:5348 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1018: + case 1021: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5336 +//line sql.y:5352 { yyLOCAL = &AssignmentExpr{Left: yyDollar[1].variableUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1019: + case 1022: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5340 +//line sql.y:5356 { yyLOCAL = &MemberOfExpr{Value: yyDollar[1].exprUnion(), JSONArr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1020: + case 1023: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5346 +//line sql.y:5362 { } - case 1021: + case 1024: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5349 +//line sql.y:5365 { } - case 1022: + case 1025: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5354 +//line sql.y:5370 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNullOp} } yyVAL.union = yyLOCAL - case 1023: + case 1026: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5358 +//line sql.y:5374 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNotNullOp} } yyVAL.union = yyLOCAL - case 1024: + case 1027: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5362 +//line sql.y:5378 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1025: + case 1028: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5366 +//line sql.y:5382 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1026: + case 1029: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5370 +//line sql.y:5386 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1027: + case 1030: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5374 +//line sql.y:5390 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: All, Right: yyDollar[4].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1028: + case 1031: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5378 +//line sql.y:5394 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1029: + case 1032: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5384 +//line sql.y:5400 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1030: + case 1033: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5388 +//line sql.y:5404 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1031: + case 1034: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5392 +//line sql.y:5408 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: true, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1032: + case 1035: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5396 +//line sql.y:5412 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: false, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1033: + case 1036: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5400 +//line sql.y:5416 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1034: + case 1037: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5404 +//line sql.y:5420 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1035: + case 1038: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5408 +//line sql.y:5424 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1036: + case 1039: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5412 +//line sql.y:5428 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1037: + case 1040: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5416 +//line sql.y:5432 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1038: + case 1041: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5420 +//line sql.y:5436 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1039: + case 1042: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5424 +//line sql.y:5440 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1040: + case 1043: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5430 +//line sql.y:5446 { } - case 1041: + case 1044: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5433 +//line sql.y:5449 { } - case 1042: + case 1045: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5439 +//line sql.y:5455 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1043: + case 1046: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5443 +//line sql.y:5459 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1044: + case 1047: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5447 +//line sql.y:5463 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1045: + case 1048: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5451 +//line sql.y:5467 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1046: + case 1049: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5455 +//line sql.y:5471 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1047: + case 1050: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5459 +//line sql.y:5475 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1048: + case 1051: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5463 +//line sql.y:5479 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAdd, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1049: + case 1052: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5467 +//line sql.y:5483 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinarySub, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1050: + case 1053: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5471 +//line sql.y:5487 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1051: + case 1054: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5475 +//line sql.y:5491 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1052: + case 1055: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5479 +//line sql.y:5495 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1053: + case 1056: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5483 +//line sql.y:5499 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1054: + case 1057: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5487 +//line sql.y:5503 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1055: + case 1058: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5491 +//line sql.y:5507 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1056: + case 1059: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5495 +//line sql.y:5511 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1057: + case 1060: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5501 +//line sql.y:5517 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1058: + case 1061: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5505 +//line sql.y:5521 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1059: + case 1062: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5509 +//line sql.y:5525 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1060: + case 1063: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5513 +//line sql.y:5529 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1061: + case 1064: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5517 +//line sql.y:5533 { yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Collation: yyDollar[3].str} } yyVAL.union = yyLOCAL - case 1062: + case 1065: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5521 +//line sql.y:5537 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1063: + case 1066: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5525 +//line sql.y:5541 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1064: + case 1067: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5529 +//line sql.y:5545 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1065: + case 1068: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5533 +//line sql.y:5549 { yyLOCAL = yyDollar[2].exprUnion() // TODO: do we really want to ignore unary '+' before any kind of literals? } yyVAL.union = yyLOCAL - case 1066: + case 1069: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5537 +//line sql.y:5553 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1067: + case 1070: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5541 +//line sql.y:5557 { yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1068: + case 1071: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5545 +//line sql.y:5561 { yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1069: + case 1072: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5549 +//line sql.y:5565 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1070: + case 1073: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5553 +//line sql.y:5569 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1071: + case 1074: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5557 +//line sql.y:5573 { yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1072: + case 1075: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5561 +//line sql.y:5577 { yyLOCAL = &MatchExpr{Columns: yyDollar[2].colNamesUnion(), Expr: yyDollar[5].exprUnion(), Option: yyDollar[6].matchExprOptionUnion()} } yyVAL.union = yyLOCAL - case 1073: + case 1076: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5565 +//line sql.y:5581 { yyLOCAL = &CastExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion(), Array: yyDollar[6].booleanUnion()} } yyVAL.union = yyLOCAL - case 1074: + case 1077: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5569 +//line sql.y:5585 { yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1075: + case 1078: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5573 +//line sql.y:5589 { yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1076: + case 1079: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5577 +//line sql.y:5593 { // 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: @@ -18251,3218 +18256,3218 @@ yydefault: yyLOCAL = &ConvertExpr{Expr: yyDollar[2].exprUnion(), Type: &ConvertType{Type: yyDollar[1].str}} } yyVAL.union = yyLOCAL - case 1077: + case 1080: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5585 +//line sql.y:5601 { yyLOCAL = &Default{ColName: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 1078: + case 1081: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5589 +//line sql.y:5605 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAddLeft, Date: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion(), Interval: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1079: + case 1082: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5593 +//line sql.y:5609 { yyLOCAL = &IntervalFuncExpr{Expr: yyDollar[3].exprUnion(), Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1080: + case 1083: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5597 +//line sql.y:5613 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[1].exprUnion(), PathList: []Expr{yyDollar[3].exprUnion()}} } yyVAL.union = yyLOCAL - case 1081: + case 1084: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5601 +//line sql.y:5617 { yyLOCAL = &JSONUnquoteExpr{JSONValue: &JSONExtractExpr{JSONDoc: yyDollar[1].exprUnion(), PathList: []Expr{yyDollar[3].exprUnion()}}} } yyVAL.union = yyLOCAL - case 1082: + case 1085: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5607 +//line sql.y:5623 { yyLOCAL = yyDollar[1].colNamesUnion() } yyVAL.union = yyLOCAL - case 1083: + case 1086: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5611 +//line sql.y:5627 { yyLOCAL = yyDollar[2].colNamesUnion() } yyVAL.union = yyLOCAL - case 1084: + case 1087: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5617 +//line sql.y:5633 { yyLOCAL = []*ColName{yyDollar[1].colNameUnion()} } yyVAL.union = yyLOCAL - case 1085: + case 1088: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5621 +//line sql.y:5637 { yySLICE := (*[]*ColName)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colNameUnion()) } - case 1086: + case 1089: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5627 +//line sql.y:5643 { yyLOCAL = BothTrimType } yyVAL.union = yyLOCAL - case 1087: + case 1090: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5631 +//line sql.y:5647 { yyLOCAL = LeadingTrimType } yyVAL.union = yyLOCAL - case 1088: + case 1091: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5635 +//line sql.y:5651 { yyLOCAL = TrailingTrimType } yyVAL.union = yyLOCAL - case 1089: + case 1092: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:5641 +//line sql.y:5657 { yyLOCAL = FrameRowsType } yyVAL.union = yyLOCAL - case 1090: + case 1093: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:5645 +//line sql.y:5661 { yyLOCAL = FrameRangeType } yyVAL.union = yyLOCAL - case 1091: + case 1094: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5652 +//line sql.y:5668 { yyLOCAL = CumeDistExprType } yyVAL.union = yyLOCAL - case 1092: + case 1095: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5656 +//line sql.y:5672 { yyLOCAL = DenseRankExprType } yyVAL.union = yyLOCAL - case 1093: + case 1096: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5660 +//line sql.y:5676 { yyLOCAL = PercentRankExprType } yyVAL.union = yyLOCAL - case 1094: + case 1097: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5664 +//line sql.y:5680 { yyLOCAL = RankExprType } yyVAL.union = yyLOCAL - case 1095: + case 1098: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5668 +//line sql.y:5684 { yyLOCAL = RowNumberExprType } yyVAL.union = yyLOCAL - case 1096: + case 1099: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5674 +//line sql.y:5690 { yyLOCAL = &FramePoint{Type: CurrentRowType} } yyVAL.union = yyLOCAL - case 1097: + case 1100: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5678 +//line sql.y:5694 { yyLOCAL = &FramePoint{Type: UnboundedPrecedingType} } yyVAL.union = yyLOCAL - case 1098: + case 1101: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5682 +//line sql.y:5698 { yyLOCAL = &FramePoint{Type: UnboundedFollowingType} } yyVAL.union = yyLOCAL - case 1099: + case 1102: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5686 +//line sql.y:5702 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1100: + case 1103: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5690 +//line sql.y:5706 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1101: + case 1104: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5694 +//line sql.y:5710 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1102: + case 1105: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5698 +//line sql.y:5714 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1103: + case 1106: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5703 +//line sql.y:5719 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1104: + case 1107: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5707 +//line sql.y:5723 { yyLOCAL = yyDollar[1].frameClauseUnion() } yyVAL.union = yyLOCAL - case 1105: + case 1108: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5713 +//line sql.y:5729 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[2].framePointUnion()} } yyVAL.union = yyLOCAL - case 1106: + case 1109: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5717 +//line sql.y:5733 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[3].framePointUnion(), End: yyDollar[5].framePointUnion()} } yyVAL.union = yyLOCAL - case 1107: + case 1110: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:5722 +//line sql.y:5738 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1108: + case 1111: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:5726 +//line sql.y:5742 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1109: + case 1112: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5731 +//line sql.y:5747 { yyVAL.identifierCI = IdentifierCI{} } - case 1110: + case 1113: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5735 +//line sql.y:5751 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1111: + case 1114: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *WindowSpecification -//line sql.y:5741 +//line sql.y:5757 { yyLOCAL = &WindowSpecification{Name: yyDollar[1].identifierCI, PartitionClause: yyDollar[2].exprsUnion(), OrderClause: yyDollar[3].orderByUnion(), FrameClause: yyDollar[4].frameClauseUnion()} } yyVAL.union = yyLOCAL - case 1112: + case 1115: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5747 +//line sql.y:5763 { yyLOCAL = &OverClause{WindowSpec: yyDollar[3].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1113: + case 1116: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5751 +//line sql.y:5767 { yyLOCAL = &OverClause{WindowName: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 1114: + case 1117: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5757 +//line sql.y:5773 { yyLOCAL = yyDollar[1].overClauseUnion() } yyVAL.union = yyLOCAL - case 1115: + case 1118: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5761 +//line sql.y:5777 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1116: + case 1119: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5766 +//line sql.y:5782 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1118: + case 1121: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5773 +//line sql.y:5789 { yyLOCAL = &NullTreatmentClause{yyDollar[1].nullTreatmentTypeUnion()} } yyVAL.union = yyLOCAL - case 1119: + case 1122: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5779 +//line sql.y:5795 { yyLOCAL = RespectNullsType } yyVAL.union = yyLOCAL - case 1120: + case 1123: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5783 +//line sql.y:5799 { yyLOCAL = IgnoreNullsType } yyVAL.union = yyLOCAL - case 1121: + case 1124: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5789 +//line sql.y:5805 { yyLOCAL = FirstValueExprType } yyVAL.union = yyLOCAL - case 1122: + case 1125: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5793 +//line sql.y:5809 { yyLOCAL = LastValueExprType } yyVAL.union = yyLOCAL - case 1123: + case 1126: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5799 +//line sql.y:5815 { yyLOCAL = FromFirstType } yyVAL.union = yyLOCAL - case 1124: + case 1127: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5803 +//line sql.y:5819 { yyLOCAL = FromLastType } yyVAL.union = yyLOCAL - case 1125: + case 1128: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5808 +//line sql.y:5824 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1127: + case 1130: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5815 +//line sql.y:5831 { yyLOCAL = &FromFirstLastClause{yyDollar[1].fromFirstLastTypeUnion()} } yyVAL.union = yyLOCAL - case 1128: + case 1131: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5821 +//line sql.y:5837 { yyLOCAL = LagExprType } yyVAL.union = yyLOCAL - case 1129: + case 1132: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5825 +//line sql.y:5841 { yyLOCAL = LeadExprType } yyVAL.union = yyLOCAL - case 1130: + case 1133: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *WindowDefinition -//line sql.y:5831 +//line sql.y:5847 { yyLOCAL = &WindowDefinition{Name: yyDollar[1].identifierCI, WindowSpec: yyDollar[4].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1131: + case 1134: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL WindowDefinitions -//line sql.y:5837 +//line sql.y:5853 { yyLOCAL = WindowDefinitions{yyDollar[1].windowDefinitionUnion()} } yyVAL.union = yyLOCAL - case 1132: + case 1135: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5841 +//line sql.y:5857 { yySLICE := (*WindowDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].windowDefinitionUnion()) } - case 1133: + case 1136: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5847 +//line sql.y:5863 { yyVAL.str = "" } - case 1134: + case 1137: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5851 +//line sql.y:5867 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } - case 1135: + case 1138: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5857 +//line sql.y:5873 { yyLOCAL = BoolVal(true) } yyVAL.union = yyLOCAL - case 1136: + case 1139: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5861 +//line sql.y:5877 { yyLOCAL = BoolVal(false) } yyVAL.union = yyLOCAL - case 1137: + case 1140: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5868 +//line sql.y:5884 { yyLOCAL = IsTrueOp } yyVAL.union = yyLOCAL - case 1138: + case 1141: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5872 +//line sql.y:5888 { yyLOCAL = IsNotTrueOp } yyVAL.union = yyLOCAL - case 1139: + case 1142: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5876 +//line sql.y:5892 { yyLOCAL = IsFalseOp } yyVAL.union = yyLOCAL - case 1140: + case 1143: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5880 +//line sql.y:5896 { yyLOCAL = IsNotFalseOp } yyVAL.union = yyLOCAL - case 1141: + case 1144: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5886 +//line sql.y:5902 { yyLOCAL = yyDollar[1].comparisonExprOperatorUnion() } yyVAL.union = yyLOCAL - case 1142: + case 1145: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5890 +//line sql.y:5906 { yyLOCAL = NullSafeEqualOp } yyVAL.union = yyLOCAL - case 1143: + case 1146: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5896 +//line sql.y:5912 { yyLOCAL = EqualOp } yyVAL.union = yyLOCAL - case 1144: + case 1147: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5900 +//line sql.y:5916 { yyLOCAL = LessThanOp } yyVAL.union = yyLOCAL - case 1145: + case 1148: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5904 +//line sql.y:5920 { yyLOCAL = GreaterThanOp } yyVAL.union = yyLOCAL - case 1146: + case 1149: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5908 +//line sql.y:5924 { yyLOCAL = LessEqualOp } yyVAL.union = yyLOCAL - case 1147: + case 1150: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5912 +//line sql.y:5928 { yyLOCAL = GreaterEqualOp } yyVAL.union = yyLOCAL - case 1148: + case 1151: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5916 +//line sql.y:5932 { yyLOCAL = NotEqualOp } yyVAL.union = yyLOCAL - case 1149: + case 1152: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5922 +//line sql.y:5938 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1150: + case 1153: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5926 +//line sql.y:5942 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1151: + case 1154: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5930 +//line sql.y:5946 { yyLOCAL = ListArg(yyDollar[1].str[2:]) markBindVariable(yylex, yyDollar[1].str[2:]) } yyVAL.union = yyLOCAL - case 1152: + case 1155: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Subquery -//line sql.y:5937 +//line sql.y:5953 { - yyLOCAL = &Subquery{yyDollar[1].selStmtUnion()} + yyLOCAL = &Subquery{yyDollar[1].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1153: + case 1156: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:5943 +//line sql.y:5959 { yyLOCAL = Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1154: + case 1157: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5947 +//line sql.y:5963 { yySLICE := (*Exprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) } - case 1155: + case 1158: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5957 +//line sql.y:5973 { yyLOCAL = &FuncExpr{Name: yyDollar[1].identifierCI, Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1156: + case 1159: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5961 +//line sql.y:5977 { yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCI, Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1157: + case 1160: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5971 +//line sql.y:5987 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("left"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1158: + case 1161: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5975 +//line sql.y:5991 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("right"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1159: + case 1162: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5979 +//line sql.y:5995 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1160: + case 1163: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5983 +//line sql.y:5999 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1161: + case 1164: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5987 +//line sql.y:6003 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1162: + case 1165: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5991 +//line sql.y:6007 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1163: + case 1166: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5995 +//line sql.y:6011 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1164: + case 1167: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5999 +//line sql.y:6015 { yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1165: + case 1168: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6003 +//line sql.y:6019 { yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL - case 1166: + case 1169: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6007 +//line sql.y:6023 { yyLOCAL = &InsertExpr{Str: yyDollar[3].exprUnion(), Pos: yyDollar[5].exprUnion(), Len: yyDollar[7].exprUnion(), NewStr: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1167: + case 1170: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6011 +//line sql.y:6027 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1168: + case 1171: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6022 +//line sql.y:6038 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("utc_date")} } yyVAL.union = yyLOCAL - case 1169: + case 1172: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6026 +//line sql.y:6042 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1170: + case 1173: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6032 +//line sql.y:6048 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("current_date")} } yyVAL.union = yyLOCAL - case 1171: + case 1174: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6036 +//line sql.y:6052 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("curdate")} } yyVAL.union = yyLOCAL - case 1172: + case 1175: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6040 +//line sql.y:6056 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1173: + case 1176: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6045 +//line sql.y:6061 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("curtime"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1174: + case 1177: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6050 +//line sql.y:6066 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1175: + case 1178: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6054 +//line sql.y:6070 { yyLOCAL = &CountStar{OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1176: + case 1179: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6058 +//line sql.y:6074 { yyLOCAL = &Count{Distinct: yyDollar[3].booleanUnion(), Args: yyDollar[4].exprsUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1177: + case 1180: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6062 +//line sql.y:6078 { yyLOCAL = &Max{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1178: + case 1181: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6066 +//line sql.y:6082 { yyLOCAL = &Min{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1179: + case 1182: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6070 +//line sql.y:6086 { yyLOCAL = &Sum{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1180: + case 1183: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6074 +//line sql.y:6090 { yyLOCAL = &Avg{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1181: + case 1184: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6078 +//line sql.y:6094 { yyLOCAL = &BitAnd{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1182: + case 1185: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6082 +//line sql.y:6098 { yyLOCAL = &BitOr{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1183: + case 1186: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6086 +//line sql.y:6102 { yyLOCAL = &BitXor{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1184: + case 1187: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6090 +//line sql.y:6106 { yyLOCAL = &Std{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1185: + case 1188: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6094 +//line sql.y:6110 { yyLOCAL = &StdDev{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1186: + case 1189: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6098 +//line sql.y:6114 { yyLOCAL = &StdPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1187: + case 1190: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6102 +//line sql.y:6118 { yyLOCAL = &StdSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1188: + case 1191: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6106 +//line sql.y:6122 { yyLOCAL = &VarPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1189: + case 1192: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6110 +//line sql.y:6126 { yyLOCAL = &VarSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1190: + case 1193: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6114 +//line sql.y:6130 { yyLOCAL = &Variance{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1191: + case 1194: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6118 +//line sql.y:6134 { 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 1192: + case 1195: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6122 +//line sql.y:6138 { yyLOCAL = &AnyValue{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1193: + case 1196: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6126 +//line sql.y:6142 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprTimestampadd, Date: yyDollar[7].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1194: + case 1197: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6130 +//line sql.y:6146 { yyLOCAL = &TimestampDiffExpr{Unit: yyDollar[3].intervalTypeUnion(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1195: + case 1198: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6134 +//line sql.y:6150 { yyLOCAL = &ExtractFuncExpr{IntervalType: yyDollar[3].intervalTypeUnion(), Expr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1196: + case 1199: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6138 +//line sql.y:6154 { yyLOCAL = &WeightStringFuncExpr{Expr: yyDollar[3].exprUnion(), As: yyDollar[4].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1197: + case 1200: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6142 +//line sql.y:6158 { yyLOCAL = &JSONPrettyExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1198: + case 1201: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6146 +//line sql.y:6162 { yyLOCAL = &JSONStorageFreeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1199: + case 1202: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6150 +//line sql.y:6166 { yyLOCAL = &JSONStorageSizeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1200: + case 1203: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6154 +//line sql.y:6170 { yyLOCAL = &JSONArrayAgg{Expr: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1201: + case 1204: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6158 +//line sql.y:6174 { yyLOCAL = &JSONObjectAgg{Key: yyDollar[3].exprUnion(), Value: yyDollar[5].exprUnion(), OverClause: yyDollar[7].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1202: + case 1205: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6162 +//line sql.y:6178 { yyLOCAL = &TrimFuncExpr{TrimFuncType: LTrimType, Type: LeadingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1203: + case 1206: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6166 +//line sql.y:6182 { yyLOCAL = &TrimFuncExpr{TrimFuncType: RTrimType, Type: TrailingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1204: + case 1207: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6170 +//line sql.y:6186 { yyLOCAL = &TrimFuncExpr{Type: yyDollar[3].trimTypeUnion(), TrimArg: yyDollar[4].exprUnion(), StringArg: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1205: + case 1208: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6174 +//line sql.y:6190 { yyLOCAL = &TrimFuncExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1206: + case 1209: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6178 +//line sql.y:6194 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1207: + case 1210: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6182 +//line sql.y:6198 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion(), Charset: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1208: + case 1211: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6186 +//line sql.y:6202 { yyLOCAL = &TrimFuncExpr{TrimArg: yyDollar[3].exprUnion(), StringArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1209: + case 1212: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6190 +//line sql.y:6206 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1210: + case 1213: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6194 +//line sql.y:6210 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion(), Pos: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1211: + case 1214: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6198 +//line sql.y:6214 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1212: + case 1215: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6202 +//line sql.y:6218 { yyLOCAL = &LockingFunc{Type: GetLock, Name: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1213: + case 1216: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6206 +//line sql.y:6222 { yyLOCAL = &LockingFunc{Type: IsFreeLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1214: + case 1217: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6210 +//line sql.y:6226 { yyLOCAL = &LockingFunc{Type: IsUsedLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1215: + case 1218: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6214 +//line sql.y:6230 { yyLOCAL = &LockingFunc{Type: ReleaseAllLocks} } yyVAL.union = yyLOCAL - case 1216: + case 1219: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6218 +//line sql.y:6234 { yyLOCAL = &LockingFunc{Type: ReleaseLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1217: + case 1220: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6222 +//line sql.y:6238 { yyLOCAL = &JSONSchemaValidFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1218: + case 1221: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6226 +//line sql.y:6242 { yyLOCAL = &JSONSchemaValidationReportFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1219: + case 1222: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6230 +//line sql.y:6246 { yyLOCAL = &JSONArrayExpr{Params: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1220: + case 1223: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6234 +//line sql.y:6250 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1221: + case 1224: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6238 +//line sql.y:6254 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1222: + case 1225: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6242 +//line sql.y:6258 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1223: + case 1226: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6246 +//line sql.y:6262 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1224: + case 1227: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6250 +//line sql.y:6266 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsEmpty, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1225: + case 1228: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6254 +//line sql.y:6270 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsSimple, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1226: + case 1229: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6258 +//line sql.y:6274 { yyLOCAL = &GeomPropertyFuncExpr{Property: Dimension, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1227: + case 1230: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6262 +//line sql.y:6278 { yyLOCAL = &GeomPropertyFuncExpr{Property: Envelope, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1228: + case 1231: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6266 +//line sql.y:6282 { yyLOCAL = &GeomPropertyFuncExpr{Property: GeometryType, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1229: + case 1232: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6270 +//line sql.y:6286 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1230: + case 1233: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6274 +//line sql.y:6290 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1231: + case 1234: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6278 +//line sql.y:6294 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1232: + case 1235: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6282 +//line sql.y:6298 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1233: + case 1236: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6286 +//line sql.y:6302 { yyLOCAL = &LinestrPropertyFuncExpr{Property: EndPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1234: + case 1237: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6290 +//line sql.y:6306 { yyLOCAL = &LinestrPropertyFuncExpr{Property: IsClosed, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1235: + case 1238: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6294 +//line sql.y:6310 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1236: + case 1239: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6298 +//line sql.y:6314 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1237: + case 1240: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6302 +//line sql.y:6318 { yyLOCAL = &LinestrPropertyFuncExpr{Property: NumPoints, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1238: + case 1241: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6306 +//line sql.y:6322 { yyLOCAL = &LinestrPropertyFuncExpr{Property: PointN, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1239: + case 1242: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6310 +//line sql.y:6326 { yyLOCAL = &LinestrPropertyFuncExpr{Property: StartPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1240: + case 1243: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6314 +//line sql.y:6330 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1241: + case 1244: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6318 +//line sql.y:6334 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1242: + case 1245: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6322 +//line sql.y:6338 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1243: + case 1246: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6326 +//line sql.y:6342 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1244: + case 1247: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6330 +//line sql.y:6346 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1245: + case 1248: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6334 +//line sql.y:6350 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1246: + case 1249: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6338 +//line sql.y:6354 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1247: + case 1250: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6342 +//line sql.y:6358 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1248: + case 1251: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6346 +//line sql.y:6362 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1249: + case 1252: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6350 +//line sql.y:6366 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1250: + case 1253: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6354 +//line sql.y:6370 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1251: + case 1254: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6358 +//line sql.y:6374 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1252: + case 1255: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6362 +//line sql.y:6378 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1253: + case 1256: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6366 +//line sql.y:6382 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1254: + case 1257: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6370 +//line sql.y:6386 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1255: + case 1258: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6374 +//line sql.y:6390 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1256: + case 1259: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6378 +//line sql.y:6394 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1257: + case 1260: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6382 +//line sql.y:6398 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1258: + case 1261: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6386 +//line sql.y:6402 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1259: + case 1262: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6390 +//line sql.y:6406 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1260: + case 1263: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6394 +//line sql.y:6410 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1261: + case 1264: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6398 +//line sql.y:6414 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1262: + case 1265: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6402 +//line sql.y:6418 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1263: + case 1266: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6406 +//line sql.y:6422 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1264: + case 1267: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6410 +//line sql.y:6426 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1265: + case 1268: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6414 +//line sql.y:6430 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1266: + case 1269: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6418 +//line sql.y:6434 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1267: + case 1270: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6422 +//line sql.y:6438 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1268: + case 1271: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6426 +//line sql.y:6442 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1269: + case 1272: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6430 +//line sql.y:6446 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1270: + case 1273: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6434 +//line sql.y:6450 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1271: + case 1274: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6438 +//line sql.y:6454 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1272: + case 1275: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6442 +//line sql.y:6458 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1273: + case 1276: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6446 +//line sql.y:6462 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1274: + case 1277: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6450 +//line sql.y:6466 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1275: + case 1278: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6454 +//line sql.y:6470 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1276: + case 1279: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6458 +//line sql.y:6474 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1277: + case 1280: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6462 +//line sql.y:6478 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1278: + case 1281: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6466 +//line sql.y:6482 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1279: + case 1282: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6470 +//line sql.y:6486 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1280: + case 1283: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6474 +//line sql.y:6490 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1281: + case 1284: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6478 +//line sql.y:6494 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1282: + case 1285: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6482 +//line sql.y:6498 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1283: + case 1286: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6486 +//line sql.y:6502 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1284: + case 1287: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6490 +//line sql.y:6506 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1285: + case 1288: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6494 +//line sql.y:6510 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1286: + case 1289: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6498 +//line sql.y:6514 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1287: + case 1290: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6502 +//line sql.y:6518 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1288: + case 1291: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6506 +//line sql.y:6522 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1289: + case 1292: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6510 +//line sql.y:6526 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1290: + case 1293: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6514 +//line sql.y:6530 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1291: + case 1294: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6518 +//line sql.y:6534 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1292: + case 1295: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6522 +//line sql.y:6538 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Area, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1293: + case 1296: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6526 +//line sql.y:6542 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Centroid, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1294: + case 1297: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6530 +//line sql.y:6546 { yyLOCAL = &PolygonPropertyFuncExpr{Property: ExteriorRing, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1295: + case 1298: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6534 +//line sql.y:6550 { yyLOCAL = &PolygonPropertyFuncExpr{Property: InteriorRingN, Polygon: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1296: + case 1299: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6538 +//line sql.y:6554 { yyLOCAL = &PolygonPropertyFuncExpr{Property: NumInteriorRings, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1297: + case 1300: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6542 +//line sql.y:6558 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: GeometryN, GeomColl: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1298: + case 1301: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6546 +//line sql.y:6562 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: NumGeometries, GeomColl: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1299: + case 1302: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6550 +//line sql.y:6566 { yyLOCAL = &GeoHashFromLatLongExpr{Longitude: yyDollar[3].exprUnion(), Latitude: yyDollar[5].exprUnion(), MaxLength: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1300: + case 1303: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6554 +//line sql.y:6570 { yyLOCAL = &GeoHashFromPointExpr{Point: yyDollar[3].exprUnion(), MaxLength: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1301: + case 1304: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6558 +//line sql.y:6574 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LatitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1302: + case 1305: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6562 +//line sql.y:6578 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LongitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1303: + case 1306: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6566 +//line sql.y:6582 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: PointFromHash, GeoHash: yyDollar[3].exprUnion(), SridOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1304: + case 1307: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6570 +//line sql.y:6586 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1305: + case 1308: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6574 +//line sql.y:6590 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1306: + case 1309: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6578 +//line sql.y:6594 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion(), Srid: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1307: + case 1310: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6582 +//line sql.y:6598 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1308: + case 1311: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6586 +//line sql.y:6602 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1309: + case 1312: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6590 +//line sql.y:6606 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion(), Bitmask: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1310: + case 1313: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6594 +//line sql.y:6610 { yyLOCAL = &JSONObjectExpr{Params: yyDollar[3].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1311: + case 1314: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6598 +//line sql.y:6614 { yyLOCAL = &JSONQuoteExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1312: + case 1315: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6602 +//line sql.y:6618 { yyLOCAL = &JSONContainsExpr{Target: yyDollar[3].exprUnion(), Candidate: yyDollar[5].exprsUnion()[0], PathList: yyDollar[5].exprsUnion()[1:]} } yyVAL.union = yyLOCAL - case 1313: + case 1316: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6606 +//line sql.y:6622 { yyLOCAL = &JSONContainsPathExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), PathList: yyDollar[7].exprsUnion()} } yyVAL.union = yyLOCAL - case 1314: + case 1317: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6610 +//line sql.y:6626 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1315: + case 1318: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6614 +//line sql.y:6630 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1316: + case 1319: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6618 +//line sql.y:6634 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1317: + case 1320: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6622 +//line sql.y:6638 { yyLOCAL = &JSONOverlapsExpr{JSONDoc1: yyDollar[3].exprUnion(), JSONDoc2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1318: + case 1321: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6626 +//line sql.y:6642 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1319: + case 1322: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6630 +//line sql.y:6646 { 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 1320: + case 1323: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6634 +//line sql.y:6650 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1321: + case 1324: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6638 +//line sql.y:6654 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1322: + case 1325: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6642 +//line sql.y:6658 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1323: + case 1326: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6646 +//line sql.y:6662 { 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 1324: + case 1327: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6650 +//line sql.y:6666 { yyLOCAL = &JSONAttributesExpr{Type: DepthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1325: + case 1328: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6654 +//line sql.y:6670 { yyLOCAL = &JSONAttributesExpr{Type: ValidAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1326: + case 1329: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6658 +//line sql.y:6674 { yyLOCAL = &JSONAttributesExpr{Type: TypeAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1327: + case 1330: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6662 +//line sql.y:6678 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1328: + case 1331: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6666 +//line sql.y:6682 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1329: + case 1332: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6670 +//line sql.y:6686 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayAppendType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1330: + case 1333: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6674 +//line sql.y:6690 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1331: + case 1334: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6678 +//line sql.y:6694 { yyLOCAL = &JSONValueModifierExpr{Type: JSONInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1332: + case 1335: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6682 +//line sql.y:6698 { yyLOCAL = &JSONValueModifierExpr{Type: JSONReplaceType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1333: + case 1336: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6686 +//line sql.y:6702 { yyLOCAL = &JSONValueModifierExpr{Type: JSONSetType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1334: + case 1337: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6690 +//line sql.y:6706 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergeType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1335: + case 1338: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6694 +//line sql.y:6710 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePatchType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1336: + case 1339: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6698 +//line sql.y:6714 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePreserveType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1337: + case 1340: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6702 +//line sql.y:6718 { yyLOCAL = &JSONRemoveExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1338: + case 1341: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6706 +//line sql.y:6722 { yyLOCAL = &JSONUnquoteExpr{JSONValue: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1339: + case 1342: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6710 +//line sql.y:6726 { yyLOCAL = &MultiPolygonExpr{PolygonParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1340: + case 1343: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6714 +//line sql.y:6730 { yyLOCAL = &MultiPointExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1341: + case 1344: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6718 +//line sql.y:6734 { yyLOCAL = &MultiLinestringExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1342: + case 1345: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6722 +//line sql.y:6738 { yyLOCAL = &PolygonExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1343: + case 1346: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6726 +//line sql.y:6742 { yyLOCAL = &LineStringExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1344: + case 1347: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6730 +//line sql.y:6746 { yyLOCAL = &PointExpr{XCordinate: yyDollar[3].exprUnion(), YCordinate: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1345: + case 1348: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6734 +//line sql.y:6750 { yyLOCAL = &ArgumentLessWindowExpr{Type: yyDollar[1].argumentLessWindowExprTypeUnion(), OverClause: yyDollar[4].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1346: + case 1349: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6738 +//line sql.y:6754 { yyLOCAL = &FirstOrLastValueExpr{Type: yyDollar[1].firstOrLastValueExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1347: + case 1350: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6742 +//line sql.y:6758 { yyLOCAL = &NtileExpr{N: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1348: + case 1351: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6746 +//line sql.y:6762 { 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 1349: + case 1352: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6750 +//line sql.y:6766 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1350: + case 1353: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6754 +//line sql.y:6770 { 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 1351: + case 1354: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6758 +//line sql.y:6774 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1352: + case 1355: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6762 +//line sql.y:6778 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1353: + case 1356: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6766 +//line sql.y:6782 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateAdd, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1354: + case 1357: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6770 +//line sql.y:6786 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateSub, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1355: + case 1358: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6774 +//line sql.y:6790 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1356: + case 1359: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6778 +//line sql.y:6794 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1361: + case 1364: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6788 +//line sql.y:6804 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1362: + case 1365: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6792 +//line sql.y:6808 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1363: + case 1366: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6796 +//line sql.y:6812 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1364: + case 1367: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6800 +//line sql.y:6816 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1365: + case 1368: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:6805 +//line sql.y:6821 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1366: + case 1369: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6809 +//line sql.y:6825 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1367: + case 1370: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6815 +//line sql.y:6831 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1368: + case 1371: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6819 +//line sql.y:6835 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1369: + case 1372: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6823 +//line sql.y:6839 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1370: + case 1373: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6827 +//line sql.y:6843 { 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 1371: + case 1374: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6831 +//line sql.y:6847 { // 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 1372: + case 1375: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6836 +//line sql.y:6852 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1373: + case 1376: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6840 +//line sql.y:6856 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), MatchType: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1374: + case 1377: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6844 +//line sql.y:6860 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1375: + case 1378: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6848 +//line sql.y:6864 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1376: + case 1379: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6852 +//line sql.y:6868 { 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 1377: + case 1380: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6856 +//line sql.y:6872 { // 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 1378: + case 1381: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6861 +//line sql.y:6877 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1379: + case 1382: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6865 +//line sql.y:6881 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1380: + case 1383: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6869 +//line sql.y:6885 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1381: + case 1384: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6873 +//line sql.y:6889 { // 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 1382: + case 1385: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6880 +//line sql.y:6896 { yyLOCAL = &ExtractValueExpr{Fragment: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1383: + case 1386: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6884 +//line sql.y:6900 { yyLOCAL = &UpdateXMLExpr{Target: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion(), NewXML: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1384: + case 1387: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6890 +//line sql.y:6906 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatBytesType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1385: + case 1388: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6894 +//line sql.y:6910 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatPicoTimeType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1386: + case 1389: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6898 +//line sql.y:6914 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsCurrentThreadIDType} } yyVAL.union = yyLOCAL - case 1387: + case 1390: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6902 +//line sql.y:6918 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsThreadIDType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1388: + case 1391: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6908 +//line sql.y:6924 { yyLOCAL = >IDFuncExpr{Type: GTIDSubsetType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1389: + case 1392: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6912 +//line sql.y:6928 { yyLOCAL = >IDFuncExpr{Type: GTIDSubtractType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1390: + case 1393: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6916 +//line sql.y:6932 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1391: + case 1394: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6920 +//line sql.y:6936 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1392: + case 1395: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6924 +//line sql.y:6940 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1393: + case 1396: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6928 +//line sql.y:6944 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1394: + case 1397: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6932 +//line sql.y:6948 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion(), Channel: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1395: + case 1398: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6937 +//line sql.y:6953 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1396: + case 1399: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6941 +//line sql.y:6957 { yyLOCAL = yyDollar[2].convertTypeUnion() } yyVAL.union = yyLOCAL - case 1397: + case 1400: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6947 +//line sql.y:6963 { yyLOCAL = IntervalDayHour } yyVAL.union = yyLOCAL - case 1398: + case 1401: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6951 +//line sql.y:6967 { yyLOCAL = IntervalDayMicrosecond } yyVAL.union = yyLOCAL - case 1399: + case 1402: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6955 +//line sql.y:6971 { yyLOCAL = IntervalDayMinute } yyVAL.union = yyLOCAL - case 1400: + case 1403: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6959 +//line sql.y:6975 { yyLOCAL = IntervalDaySecond } yyVAL.union = yyLOCAL - case 1401: + case 1404: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6963 +//line sql.y:6979 { yyLOCAL = IntervalHourMicrosecond } yyVAL.union = yyLOCAL - case 1402: + case 1405: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6967 +//line sql.y:6983 { yyLOCAL = IntervalHourMinute } yyVAL.union = yyLOCAL - case 1403: + case 1406: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6971 +//line sql.y:6987 { yyLOCAL = IntervalHourSecond } yyVAL.union = yyLOCAL - case 1404: + case 1407: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6975 +//line sql.y:6991 { yyLOCAL = IntervalMinuteMicrosecond } yyVAL.union = yyLOCAL - case 1405: + case 1408: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6979 +//line sql.y:6995 { yyLOCAL = IntervalMinuteSecond } yyVAL.union = yyLOCAL - case 1406: + case 1409: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6983 +//line sql.y:6999 { yyLOCAL = IntervalSecondMicrosecond } yyVAL.union = yyLOCAL - case 1407: + case 1410: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6987 +//line sql.y:7003 { yyLOCAL = IntervalYearMonth } yyVAL.union = yyLOCAL - case 1408: + case 1411: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6991 +//line sql.y:7007 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1409: + case 1412: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6995 +//line sql.y:7011 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1410: + case 1413: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6999 +//line sql.y:7015 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1411: + case 1414: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7003 +//line sql.y:7019 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1412: + case 1415: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7007 +//line sql.y:7023 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1413: + case 1416: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7011 +//line sql.y:7027 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1414: + case 1417: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7015 +//line sql.y:7031 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1415: + case 1418: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7019 +//line sql.y:7035 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1416: + case 1419: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7023 +//line sql.y:7039 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1417: + case 1420: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7029 +//line sql.y:7045 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1418: + case 1421: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7033 +//line sql.y:7049 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1419: + case 1422: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7037 +//line sql.y:7053 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1420: + case 1423: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7041 +//line sql.y:7057 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1421: + case 1424: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7045 +//line sql.y:7061 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1422: + case 1425: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7049 +//line sql.y:7065 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1423: + case 1426: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7053 +//line sql.y:7069 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1424: + case 1427: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7057 +//line sql.y:7073 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1425: + case 1428: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7061 +//line sql.y:7077 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1426: + case 1429: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7065 +//line sql.y:7081 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1427: + case 1430: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7069 +//line sql.y:7085 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1428: + case 1431: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7073 +//line sql.y:7089 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1429: + case 1432: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7077 +//line sql.y:7093 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1430: + case 1433: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7081 +//line sql.y:7097 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1431: + case 1434: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7085 +//line sql.y:7101 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1432: + case 1435: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7089 +//line sql.y:7105 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1433: + case 1436: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7093 +//line sql.y:7109 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1434: + case 1437: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7097 +//line sql.y:7113 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1437: + case 1440: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:7107 +//line sql.y:7123 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1438: + case 1441: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:7111 +//line sql.y:7127 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1439: + case 1442: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:7115 +//line sql.y:7131 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 1440: + case 1443: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7125 +//line sql.y:7141 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("if"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1441: + case 1444: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7129 +//line sql.y:7145 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("database"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1442: + case 1445: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7133 +//line sql.y:7149 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("schema"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1443: + case 1446: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7137 +//line sql.y:7153 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("mod"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1444: + case 1447: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7141 +//line sql.y:7157 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("replace"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1445: + case 1448: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7147 +//line sql.y:7163 { yyLOCAL = NoOption } yyVAL.union = yyLOCAL - case 1446: + case 1449: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7151 +//line sql.y:7167 { yyLOCAL = BooleanModeOpt } yyVAL.union = yyLOCAL - case 1447: + case 1450: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7155 +//line sql.y:7171 { yyLOCAL = NaturalLanguageModeOpt } yyVAL.union = yyLOCAL - case 1448: + case 1451: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7159 +//line sql.y:7175 { yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } yyVAL.union = yyLOCAL - case 1449: + case 1452: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7163 +//line sql.y:7179 { yyLOCAL = QueryExpansionOpt } yyVAL.union = yyLOCAL - case 1450: + case 1453: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7169 +//line sql.y:7185 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } - case 1451: + case 1454: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7173 +//line sql.y:7189 { yyVAL.str = string(yyDollar[1].str) } - case 1452: + case 1455: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7177 +//line sql.y:7193 { yyVAL.str = string(yyDollar[1].str) } - case 1453: + case 1456: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7183 +//line sql.y:7199 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1454: + case 1457: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7187 +//line sql.y:7203 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } yyVAL.union = yyLOCAL - case 1455: + case 1458: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7191 +//line sql.y:7207 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } yyVAL.union = yyLOCAL - case 1456: + case 1459: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7197 +//line sql.y:7213 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1457: + case 1460: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7201 +//line sql.y:7217 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } yyVAL.union = yyLOCAL - case 1458: + case 1461: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7205 +//line sql.y:7221 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1459: + case 1462: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7209 +//line sql.y:7225 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1460: + case 1463: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7213 +//line sql.y:7229 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale } yyVAL.union = yyLOCAL - case 1461: + case 1464: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7219 +//line sql.y:7235 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1462: + case 1465: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7223 +//line sql.y:7239 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1463: + case 1466: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7227 +//line sql.y:7243 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1464: + case 1467: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7231 +//line sql.y:7247 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1465: + case 1468: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7235 +//line sql.y:7251 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1466: + case 1469: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7239 +//line sql.y:7255 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1467: + case 1470: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7243 +//line sql.y:7259 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1468: + case 1471: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7247 +//line sql.y:7263 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1469: + case 1472: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7251 +//line sql.y:7267 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1470: + case 1473: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7255 +//line sql.y:7271 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1471: + case 1474: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7261 +//line sql.y:7277 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1472: + case 1475: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7265 +//line sql.y:7281 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1473: + case 1476: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7270 +//line sql.y:7286 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1474: + case 1477: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7274 +//line sql.y:7290 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1475: + case 1478: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7279 +//line sql.y:7295 { yyVAL.str = string("") } - case 1476: + case 1479: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7283 +//line sql.y:7299 { yyVAL.str = encodeSQLString(yyDollar[2].str) } - case 1477: + case 1480: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:7289 +//line sql.y:7305 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL - case 1478: + case 1481: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7293 +//line sql.y:7309 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) } - case 1479: + case 1482: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:7299 +//line sql.y:7315 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1480: + case 1483: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7304 +//line sql.y:7320 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1481: + case 1484: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7308 +//line sql.y:7324 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1482: + case 1485: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7314 +//line sql.y:7330 { yyLOCAL = &ColName{Name: yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1483: + case 1486: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7318 +//line sql.y:7334 { yyLOCAL = &ColName{Name: NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 1484: + case 1487: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:7322 +//line sql.y:7338 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].identifierCS}, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1485: + case 1488: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:7326 +//line sql.y:7342 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}, Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 1486: + case 1489: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7332 +//line sql.y:7348 { yyLOCAL = yyDollar[1].colNameUnion() } yyVAL.union = yyLOCAL - case 1487: + case 1490: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7336 +//line sql.y:7352 { yyLOCAL = &Offset{V: convertStringToInt(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1488: + case 1491: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7342 +//line sql.y:7358 { // TODO(sougou): Deprecate this construct. if yyDollar[1].identifierCI.Lowered() != "value" { @@ -21472,442 +21477,442 @@ yydefault: yyLOCAL = NewIntLiteral("1") } yyVAL.union = yyLOCAL - case 1489: + case 1492: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7351 +//line sql.y:7367 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1490: + case 1493: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7355 +//line sql.y:7371 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1491: + case 1494: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7360 +//line sql.y:7376 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1492: + case 1495: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7364 +//line sql.y:7380 { yyLOCAL = &GroupBy{Exprs: yyDollar[3].exprsUnion(), WithRollup: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 1493: + case 1496: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7369 +//line sql.y:7385 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1494: + case 1497: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7373 +//line sql.y:7389 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1495: + case 1498: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7379 +//line sql.y:7395 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1496: + case 1499: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7383 +//line sql.y:7399 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1497: + case 1500: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *NamedWindow -//line sql.y:7389 +//line sql.y:7405 { yyLOCAL = &NamedWindow{yyDollar[2].windowDefinitionsUnion()} } yyVAL.union = yyLOCAL - case 1498: + case 1501: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7395 +//line sql.y:7411 { yyLOCAL = NamedWindows{yyDollar[1].namedWindowUnion()} } yyVAL.union = yyLOCAL - case 1499: + case 1502: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7399 +//line sql.y:7415 { yySLICE := (*NamedWindows)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].namedWindowUnion()) } - case 1500: + case 1503: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7404 +//line sql.y:7420 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1501: + case 1504: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7408 +//line sql.y:7424 { yyLOCAL = yyDollar[1].namedWindowsUnion() } yyVAL.union = yyLOCAL - case 1502: + case 1505: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7413 +//line sql.y:7429 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1503: + case 1506: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7417 +//line sql.y:7433 { yyLOCAL = yyDollar[1].orderByUnion() } yyVAL.union = yyLOCAL - case 1504: + case 1507: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7423 +//line sql.y:7439 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 1505: + case 1508: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7429 +//line sql.y:7445 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 1506: + case 1509: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7433 +//line sql.y:7449 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) } - case 1507: + case 1510: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:7439 +//line sql.y:7455 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 1508: + case 1511: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7444 +//line sql.y:7460 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1509: + case 1512: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7448 +//line sql.y:7464 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1510: + case 1513: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7452 +//line sql.y:7468 { yyLOCAL = DescOrder } yyVAL.union = yyLOCAL - case 1511: + case 1514: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:7457 +//line sql.y:7473 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1512: + case 1515: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Limit -//line sql.y:7461 +//line sql.y:7477 { yyLOCAL = yyDollar[1].limitUnion() } yyVAL.union = yyLOCAL - case 1513: + case 1516: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:7467 +//line sql.y:7483 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1514: + case 1517: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7471 +//line sql.y:7487 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1515: + case 1518: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7475 +//line sql.y:7491 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1516: + case 1519: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7480 +//line sql.y:7496 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1517: + case 1520: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7484 +//line sql.y:7500 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1518: + case 1521: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7488 +//line sql.y:7504 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1519: + case 1522: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7492 +//line sql.y:7508 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1520: + case 1523: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7496 +//line sql.y:7512 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1521: + case 1524: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7503 +//line sql.y:7519 { yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL - case 1522: + case 1525: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7507 +//line sql.y:7523 { yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL - case 1523: + case 1526: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7511 +//line sql.y:7527 { yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL - case 1524: + case 1527: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7515 +//line sql.y:7531 { yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL - case 1525: + case 1528: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7521 +//line sql.y:7537 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1526: + case 1529: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7525 +//line sql.y:7541 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1527: + case 1530: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7529 +//line sql.y:7545 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1528: + case 1531: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7533 +//line sql.y:7549 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1529: + case 1532: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7538 +//line sql.y:7554 { yyVAL.str = "" } - case 1530: + case 1533: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7542 +//line sql.y:7558 { yyVAL.str = string(yyDollar[3].str) } - case 1531: + case 1534: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7546 +//line sql.y:7562 { yyVAL.str = string(yyDollar[3].str) } - case 1532: + case 1535: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7550 +//line sql.y:7566 { yyVAL.str = string(yyDollar[3].str) } - case 1533: + case 1536: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7555 +//line sql.y:7571 { yyVAL.str = "" } - case 1534: + case 1537: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7559 +//line sql.y:7575 { yyVAL.str = yyDollar[3].str } - case 1535: + case 1538: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7565 +//line sql.y:7581 { yyVAL.str = string(yyDollar[1].str) } - case 1536: + case 1539: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7569 +//line sql.y:7585 { yyVAL.str = string(yyDollar[1].str) } - case 1537: + case 1540: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7574 +//line sql.y:7590 { yyVAL.str = "" } - case 1538: + case 1541: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7578 +//line sql.y:7594 { yyVAL.str = yyDollar[2].str } - case 1539: + case 1542: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7583 +//line sql.y:7599 { yyVAL.str = "cascaded" } - case 1540: + case 1543: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7587 +//line sql.y:7603 { yyVAL.str = string(yyDollar[1].str) } - case 1541: + case 1544: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7591 +//line sql.y:7607 { yyVAL.str = string(yyDollar[1].str) } - case 1542: + case 1545: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Definer -//line sql.y:7596 +//line sql.y:7612 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1543: + case 1546: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7600 +//line sql.y:7616 { yyLOCAL = yyDollar[3].definerUnion() } yyVAL.union = yyLOCAL - case 1544: + case 1547: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Definer -//line sql.y:7606 +//line sql.y:7622 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1545: + case 1548: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7612 +//line sql.y:7628 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1546: + case 1549: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Definer -//line sql.y:7618 +//line sql.y:7634 { yyLOCAL = &Definer{ Name: yyDollar[1].str, @@ -21915,433 +21920,464 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1547: + case 1550: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7627 +//line sql.y:7643 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 1548: + case 1551: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7631 +//line sql.y:7647 { yyVAL.str = formatIdentifier(yyDollar[1].str) } - case 1549: + case 1552: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7636 +//line sql.y:7652 { yyVAL.str = "" } - case 1550: + case 1553: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7640 +//line sql.y:7656 { yyVAL.str = formatAddress(yyDollar[1].str) } - case 1551: + case 1554: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:7646 +//line sql.y:7662 { yyLOCAL = ForUpdateLock } yyVAL.union = yyLOCAL - case 1552: + case 1555: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:7650 +//line sql.y:7666 { yyLOCAL = ForUpdateLockNoWait } yyVAL.union = yyLOCAL - case 1553: + case 1556: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7654 +//line sql.y:7670 { yyLOCAL = ForUpdateLockSkipLocked } yyVAL.union = yyLOCAL - case 1554: + case 1557: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:7658 +//line sql.y:7674 { yyLOCAL = ForShareLock } yyVAL.union = yyLOCAL - case 1555: + case 1558: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:7662 +//line sql.y:7678 { yyLOCAL = ForShareLockNoWait } yyVAL.union = yyLOCAL - case 1556: + case 1559: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7666 +//line sql.y:7682 { yyLOCAL = ForShareLockSkipLocked } yyVAL.union = yyLOCAL - case 1557: + case 1560: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7670 +//line sql.y:7686 { yyLOCAL = ShareModeLock } yyVAL.union = yyLOCAL - case 1558: + case 1561: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7676 +//line sql.y:7692 { 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 1559: + case 1562: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7680 +//line sql.y:7696 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: ColumnCharset{}, FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1560: + case 1563: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7684 +//line sql.y:7700 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].columnCharset, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1561: + case 1564: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7689 +//line sql.y:7705 { yyVAL.str = "" } - case 1562: + case 1565: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7693 +//line sql.y:7709 { yyVAL.str = " format csv" + yyDollar[3].str } - case 1563: + case 1566: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7697 +//line sql.y:7713 { yyVAL.str = " format text" + yyDollar[3].str } - case 1564: + case 1567: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7702 +//line sql.y:7718 { yyVAL.str = "" } - case 1565: + case 1568: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7706 +//line sql.y:7722 { yyVAL.str = " header" } - case 1566: + case 1569: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7711 +//line sql.y:7727 { yyVAL.str = "" } - case 1567: + case 1570: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7715 +//line sql.y:7731 { yyVAL.str = " manifest on" } - case 1568: + case 1571: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7719 +//line sql.y:7735 { yyVAL.str = " manifest off" } - case 1569: + case 1572: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7724 +//line sql.y:7740 { yyVAL.str = "" } - case 1570: + case 1573: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7728 +//line sql.y:7744 { yyVAL.str = " overwrite on" } - case 1571: + case 1574: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7732 +//line sql.y:7748 { yyVAL.str = " overwrite off" } - case 1572: + case 1575: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7738 +//line sql.y:7754 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1573: + case 1576: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7743 +//line sql.y:7759 { yyVAL.str = "" } - case 1574: + case 1577: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7747 +//line sql.y:7763 { yyVAL.str = " lines" + yyDollar[2].str } - case 1575: + case 1578: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7753 +//line sql.y:7769 { yyVAL.str = yyDollar[1].str } - case 1576: + case 1579: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7757 +//line sql.y:7773 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1577: + case 1580: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7763 +//line sql.y:7779 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 1578: + case 1581: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7767 +//line sql.y:7783 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1579: + case 1582: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7772 +//line sql.y:7788 { yyVAL.str = "" } - case 1580: + case 1583: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7776 +//line sql.y:7792 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 1581: + case 1584: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7782 +//line sql.y:7798 { yyVAL.str = yyDollar[1].str } - case 1582: + case 1585: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7786 +//line sql.y:7802 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1583: + case 1586: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7792 +//line sql.y:7808 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1584: + case 1587: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7796 +//line sql.y:7812 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 1585: + case 1588: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7800 +//line sql.y:7816 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 1586: + case 1589: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7805 +//line sql.y:7821 { yyVAL.str = "" } - case 1587: + case 1590: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7809 +//line sql.y:7825 { yyVAL.str = " optionally" } - case 1588: + case 1591: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Insert -//line sql.y:7822 +//line sql.y:7838 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion(), RowAlias: yyDollar[3].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1589: + case 1592: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:7826 +//line sql.y:7842 { - yyLOCAL = &Insert{Rows: yyDollar[1].selStmtUnion()} + yyLOCAL = &Insert{Rows: yyDollar[1].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1590: + case 1593: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *Insert -//line sql.y:7830 +//line sql.y:7846 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion(), RowAlias: yyDollar[6].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1591: + case 1594: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:7834 +//line sql.y:7850 { yyLOCAL = &Insert{Columns: []IdentifierCI{}, Rows: yyDollar[4].valuesUnion(), RowAlias: yyDollar[5].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1592: + case 1595: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7838 +//line sql.y:7854 { - yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].selStmtUnion()} + yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1593: + case 1596: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:7844 +//line sql.y:7860 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1594: + case 1597: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:7848 +//line sql.y:7864 { yyLOCAL = Columns{yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1595: + case 1598: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7852 +//line sql.y:7868 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1596: + case 1599: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:7856 +//line sql.y:7872 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].identifierCI) } - case 1597: + case 1600: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:7861 +//line sql.y:7877 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1598: + case 1601: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:7865 +//line sql.y:7881 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS} } yyVAL.union = yyLOCAL - case 1599: + case 1602: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:7869 +//line sql.y:7885 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS, Columns: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1600: + case 1603: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7874 +//line sql.y:7890 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1601: + case 1604: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7878 +//line sql.y:7894 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 1602: + case 1605: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:7884 +//line sql.y:7900 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 1603: + case 1606: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7888 +//line sql.y:7904 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 1604: + case 1607: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL Values +//line sql.y:7910 + { + yyLOCAL = Values{yyDollar[1].valTupleUnion()} + } + yyVAL.union = yyLOCAL + case 1608: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:7914 + { + yySLICE := (*Values)(yyIaddr(yyVAL.union)) + *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) + } + case 1609: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7894 +//line sql.y:7920 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1605: + case 1610: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL ValTuple +//line sql.y:7924 + { + yyLOCAL = ValTuple{} + } + yyVAL.union = yyLOCAL + case 1611: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL ValTuple +//line sql.y:7930 + { + yyLOCAL = yyDollar[1].valTupleUnion() + } + yyVAL.union = yyLOCAL + case 1612: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7898 +//line sql.y:7934 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 1606: + case 1613: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7904 +//line sql.y:7940 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 1607: + case 1614: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7908 +//line sql.y:7946 { yyLOCAL = ValTuple(yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 1608: + case 1617: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7913 +//line sql.y:7956 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -22350,300 +22386,300 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1609: + case 1618: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7923 +//line sql.y:7966 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 1610: + case 1619: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7927 +//line sql.y:7970 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 1611: + case 1620: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:7933 +//line sql.y:7976 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1613: + case 1622: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7940 +//line sql.y:7983 { yyVAL.str = "charset" } - case 1616: + case 1625: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7950 +//line sql.y:7993 { yyLOCAL = NewStrLiteral(yyDollar[1].identifierCI.String()) } yyVAL.union = yyLOCAL - case 1617: + case 1626: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7954 +//line sql.y:7997 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1618: + case 1627: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7958 +//line sql.y:8001 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 1621: + case 1630: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7967 +//line sql.y:8010 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1622: + case 1631: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7969 +//line sql.y:8012 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1623: + case 1632: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7972 +//line sql.y:8015 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1624: + case 1633: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7974 +//line sql.y:8017 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1625: + case 1634: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7977 +//line sql.y:8020 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1626: + case 1635: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:7979 +//line sql.y:8022 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1627: + case 1636: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:7982 +//line sql.y:8025 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1628: + case 1637: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:7984 +//line sql.y:8027 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1629: + case 1638: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7987 +//line sql.y:8030 { yyVAL.empty = struct{}{} } - case 1630: + case 1639: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7989 +//line sql.y:8032 { yyVAL.empty = struct{}{} } - case 1631: + case 1640: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7991 +//line sql.y:8034 { yyVAL.empty = struct{}{} } - case 1632: + case 1641: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:7995 +//line sql.y:8038 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 1633: + case 1642: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:8000 +//line sql.y:8043 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1634: + case 1643: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:8004 +//line sql.y:8047 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 1635: + case 1644: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:8009 +//line sql.y:8052 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1636: + case 1645: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:8011 +//line sql.y:8054 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 1637: + case 1646: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:8015 +//line sql.y:8058 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].identifierCI.String())} } yyVAL.union = yyLOCAL - case 1638: + case 1647: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8021 +//line sql.y:8064 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1639: + case 1648: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8025 +//line sql.y:8068 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1641: + case 1650: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8032 +//line sql.y:8075 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1642: + case 1651: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8038 +//line sql.y:8081 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1643: + case 1652: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8042 +//line sql.y:8085 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1644: + case 1653: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8048 +//line sql.y:8091 { yyVAL.identifierCS = NewIdentifierCS("") } - case 1645: + case 1654: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8052 +//line sql.y:8095 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 1647: + case 1656: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8059 +//line sql.y:8102 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1648: + case 1657: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:8065 +//line sql.y:8108 { yyLOCAL = &Kill{Type: yyDollar[2].killTypeUnion(), ProcesslistID: convertStringToUInt64(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 1649: + case 1658: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL KillType -//line sql.y:8071 +//line sql.y:8114 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1650: + case 1659: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:8075 +//line sql.y:8118 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1651: + case 1660: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:8079 +//line sql.y:8122 { yyLOCAL = QueryType } yyVAL.union = yyLOCAL - case 2283: + case 2296: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8739 +//line sql.y:8786 { } - case 2284: + case 2297: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8744 +//line sql.y:8791 { } - case 2285: + case 2298: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8748 +//line sql.y:8795 { skipToEnd(yylex) } - case 2286: + case 2299: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8753 +//line sql.y:8800 { skipToEnd(yylex) } - case 2287: + case 2300: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8757 +//line sql.y:8804 { skipToEnd(yylex) } - case 2288: + case 2301: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8761 +//line sql.y:8808 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index bf1a793e7e8..b6835ad32a5 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -60,14 +60,15 @@ func markBindVariable(yylex yyLexer, bvar string) { } %union { - statement Statement - selStmt SelectStatement - tableExpr TableExpr - expr Expr - colTuple ColTuple - optVal Expr - constraintInfo ConstraintInfo - alterOption AlterOption + statement Statement + selStmt SelectStatement + tableStmt TableStatement + tableExpr TableExpr + expr Expr + colTuple ColTuple + optVal Expr + constraintInfo ConstraintInfo + alterOption AlterOption ins *Insert colName *ColName @@ -401,6 +402,7 @@ func markBindVariable(yylex yyLexer, bvar string) { %token NESTED NETWORK_NAMESPACE NOWAIT NULLS OJ OLD OPTIONAL ORDINALITY ORGANIZATION OTHERS PARTIAL PATH PERSIST PERSIST_ONLY PRECEDING PRIVILEGE_CHECKS_USER PROCESS %token RANDOM REFERENCE REQUIRE_ROW_FORMAT RESOURCE RESPECT RESTART RETAIN REUSE ROLE SECONDARY SECONDARY_ENGINE SECONDARY_ENGINE_ATTRIBUTE SECONDARY_LOAD SECONDARY_UNLOAD SIMPLE SKIP SRID %token THREAD_PRIORITY TIES UNBOUNDED VCPU VISIBLE RETURNING +%token MANUAL PARALLEL QUALIFY TABLESAMPLE // Performance Schema Functions %token FORMAT_BYTES FORMAT_PICO_TIME PS_CURRENT_THREAD_ID PS_THREAD_ID @@ -434,7 +436,7 @@ func markBindVariable(yylex yyLexer, bvar string) { %type prepare_statement execute_statement deallocate_statement %type stream_statement vstream_statement insert_statement update_statement delete_statement set_statement set_transaction_statement %type create_statement alter_statement rename_statement drop_statement truncate_statement flush_statement do_statement -%type select_statement select_stmt_with_into query_expression_parens query_expression query_expression_body query_primary +%type select_statement select_stmt_with_into query_expression_parens query_expression query_expression_body query_primary values_statement %type with_clause_opt with_clause %type common_table_expr %type with_list @@ -517,8 +519,8 @@ func markBindVariable(yylex yyLexer, bvar string) { %type is_suffix %type col_tuple %type expression_list expression_list_opt window_partition_clause_opt -%type tuple_list -%type row_tuple tuple_or_empty +%type row_tuple_list val_tuple_list +%type val_tuple row_tuple val_tuple_or_empty row_tuple_or_empty val_or_row_tuple %type subquery %type derived_table %type column_name after_opt @@ -769,7 +771,7 @@ query_expression_parens: } | openb query_expression locking_clause closeb { - setLockInSelect($2, $3) + setLockIfPossible(yylex, $2, $3) $$ = $2 } @@ -810,9 +812,9 @@ query_expression: | with_clause query_expression_body order_by_opt limit_opt { $2.SetWith($1) - $2.SetOrderBy($3) - $2.SetLimit($4) - $$ = $2 + $2.SetOrderBy($3) + $2.SetLimit($4) + $$ = $2 } | with_clause query_expression_parens limit_clause { @@ -865,7 +867,7 @@ query_expression } | query_expression locking_clause { - setLockInSelect($1, $2) + setLockIfPossible(yylex, $1, $2) $$ = $1 } | query_expression_parens @@ -884,27 +886,37 @@ select_stmt_with_into: } | query_expression into_clause { - $1.SetInto($2) + setIntoIfPossible(yylex, $1, $2) $$ = $1 } | query_expression into_clause locking_clause { - $1.SetInto($2) - $1.SetLock($3) + setIntoIfPossible(yylex, $1, $2) + setLockIfPossible(yylex, $1, $3) $$ = $1 } | query_expression locking_clause into_clause { - $1.SetInto($3) - $1.SetLock($2) + setLockIfPossible(yylex, $1, $2) + setIntoIfPossible(yylex, $1, $3) $$ = $1 } | query_expression_parens into_clause { - $1.SetInto($2) + setIntoIfPossible(yylex, $1, $2) $$ = $1 } +values_statement: + VALUES comment_opt LIST_ARG + { + $$ = &ValuesStatement{Comments: Comments($2).Parsed(), ListArg: ListArg($3[2:])} + } +| VALUES comment_opt row_tuple_list + { + $$ = &ValuesStatement{Comments: Comments($2).Parsed(), Rows: $3} + } + stream_statement: STREAM comment_opt select_expression FROM table_name { @@ -928,6 +940,10 @@ query_primary: { $$ = NewSelect(Comments($2), $4/*SelectExprs*/, $3/*options*/, nil, $5/*from*/, NewWhere(WhereClause, $6), $7, NewWhere(HavingClause, $8), $9) } +| values_statement + { + $$ = $1 + } insert_statement: insert_or_replace comment_opt ignore_opt into_table_name opt_partition_clause insert_data on_dup_opt @@ -3871,7 +3887,7 @@ subpartition_definition_attribute_list_opt: } partition_value_range: - VALUES LESS THAN row_tuple + VALUES LESS THAN val_tuple { $$ = &PartitionValueRange{ Type: LessThanType, @@ -3885,7 +3901,7 @@ partition_value_range: Maxvalue: true, } } -| VALUES IN row_tuple +| VALUES IN val_tuple { $$ = &PartitionValueRange{ Type: InType, @@ -5918,7 +5934,7 @@ any_all_compare: } col_tuple: - row_tuple + val_tuple { $$ = $1 } @@ -7818,7 +7834,7 @@ optionally_opt: // Because the rules are together, the parser can keep shifting // the tokens until it disambiguates a as sql_id and select as keyword. insert_data: - VALUES tuple_list row_alias_opt + VALUES val_tuple_list row_alias_opt { $$ = &Insert{Rows: $2, RowAlias: $3} } @@ -7826,11 +7842,11 @@ insert_data: { $$ = &Insert{Rows: $1} } -| openb ins_column_list closeb VALUES tuple_list row_alias_opt +| openb ins_column_list closeb VALUES val_tuple_list row_alias_opt { $$ = &Insert{Columns: $2, Rows: $5, RowAlias: $6} } -| openb closeb VALUES tuple_list row_alias_opt +| openb closeb VALUES val_tuple_list row_alias_opt { $$ = &Insert{Columns: []IdentifierCI{}, Rows: $4, RowAlias: $5} } @@ -7879,37 +7895,64 @@ on_dup_opt: $$ = $5 } -tuple_list: - tuple_or_empty +row_tuple_list: + row_tuple_or_empty { $$ = Values{$1} } -| tuple_list ',' tuple_or_empty +| row_tuple_list ',' row_tuple_or_empty { $$ = append($1, $3) } -tuple_or_empty: +val_tuple_list: + val_tuple_or_empty + { + $$ = Values{$1} + } +| val_tuple_list ',' val_tuple_or_empty + { + $$ = append($1, $3) + } + +row_tuple_or_empty: row_tuple { $$ = $1 } +| ROW openb closeb + { + $$ = ValTuple{} + } + +val_tuple_or_empty: + val_tuple + { + $$ = $1 + } | openb closeb { $$ = ValTuple{} } -row_tuple: +val_tuple: openb expression_list closeb { $$ = ValTuple($2) } -| ROW openb expression_list closeb + +row_tuple: + ROW openb expression_list closeb { $$ = ValTuple($3) } + +val_or_row_tuple: + val_tuple +| row_tuple + tuple_expression: - row_tuple + val_or_row_tuple { if len($1) == 1 { $$ = $1[0] @@ -8443,6 +8486,7 @@ non_reserved_keyword: | LONGBLOB | LONGTEXT | LTRIM %prec FUNCTION_CALL_NON_KEYWORD +| MANUAL | MANIFEST | MASTER_COMPRESSION_ALGORITHMS | MASTER_PUBLIC_KEY_PATH @@ -8488,6 +8532,7 @@ non_reserved_keyword: | OTHERS | OVERWRITE | PACK_KEYS +| PARALLEL | PARSER | PARTIAL | PARTITIONING @@ -8511,6 +8556,7 @@ non_reserved_keyword: | PROCEDURE | PROCESSLIST | PURGE +| QUALIFY | QUERIES | QUERY | RANDOM @@ -8638,6 +8684,7 @@ non_reserved_keyword: | SUBPARTITIONS | SUM %prec FUNCTION_CALL_NON_KEYWORD | TABLES +| TABLESAMPLE | TABLESPACE | TEMPORARY | TEMPTABLE diff --git a/go/vt/sqlparser/testdata/mysql_keywords.txt b/go/vt/sqlparser/testdata/mysql_keywords.txt index 9e5c6eab6d8..dc24fe94c0a 100644 --- a/go/vt/sqlparser/testdata/mysql_keywords.txt +++ b/go/vt/sqlparser/testdata/mysql_keywords.txt @@ -1,5 +1,5 @@ // Code generated by `SELECT * FROM INFORMATION_SCHEMA.KEYWORDS`. -// Reference: https://dev.mysql.com/doc/refman/8.0/en/information-schema-keywords-table.html +// Reference: https://dev.mysql.com/doc/refman/8.4/en/information-schema-keywords-table.html // DO NOT EDIT. WORD RESERVED ACCESSIBLE 1 @@ -23,8 +23,11 @@ AS 1 ASC 1 ASCII 0 ASENSITIVE 1 +ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS 0 AT 0 ATTRIBUTE 0 +AUTHENTICATION 0 +AUTO 0 AUTOEXTEND_SIZE 0 AUTO_INCREMENT 0 AVG 0 @@ -32,6 +35,7 @@ AVG_ROW_LENGTH 0 BACKUP 0 BEFORE 1 BEGIN 0 +BERNOULLI 0 BETWEEN 1 BIGINT 1 BINARY 1 @@ -44,6 +48,7 @@ BOOLEAN 0 BOTH 1 BTREE 0 BUCKETS 0 +BULK 0 BY 1 BYTE 0 CACHE 0 @@ -53,6 +58,7 @@ CASCADED 0 CASE 1 CATALOG_NAME 0 CHAIN 0 +CHALLENGE_RESPONSE 0 CHANGE 1 CHANGED 0 CHANNEL 0 @@ -181,6 +187,7 @@ EXPLAIN 1 EXPORT 0 EXTENDED 0 EXTENT_SIZE 0 +FACTOR 0 FAILED_LOGIN_ATTEMPTS 0 FALSE 1 FAST 0 @@ -190,6 +197,7 @@ FIELDS 0 FILE 0 FILE_BLOCK_SIZE 0 FILTER 0 +FINISH 0 FIRST 0 FIRST_VALUE 1 FIXED 0 @@ -209,6 +217,7 @@ FULL 0 FULLTEXT 1 FUNCTION 1 GENERAL 0 +GENERATE 0 GENERATED 1 GEOMCOLLECTION 0 GEOMETRY 0 @@ -216,6 +225,7 @@ GEOMETRYCOLLECTION 0 GET 1 GET_FORMAT 0 GET_MASTER_PUBLIC_KEY 0 +GET_SOURCE_PUBLIC_KEY 0 GLOBAL 0 GRANT 1 GRANTS 0 @@ -223,6 +233,8 @@ GROUP 1 GROUPING 1 GROUPS 1 GROUP_REPLICATION 0 +GTIDS 0 +GTID_ONLY 0 HANDLER 0 HASH 0 HAVING 1 @@ -246,7 +258,9 @@ INACTIVE 0 INDEX 1 INDEXES 0 INFILE 1 +INITIAL 0 INITIAL_SIZE 0 +INITIATE 0 INNER 1 INOUT 1 INSENSITIVE 1 @@ -261,6 +275,7 @@ INT3 1 INT4 1 INT8 1 INTEGER 1 +INTERSECT 1 INTERVAL 1 INTO 1 INVISIBLE 0 @@ -279,6 +294,7 @@ JSON 0 JSON_TABLE 1 JSON_VALUE 0 KEY 1 +KEYRING 0 KEYS 1 KEY_BLOCK_SIZE 0 KILL 1 @@ -307,6 +323,7 @@ LOCALTIMESTAMP 1 LOCK 1 LOCKED 0 LOCKS 0 +LOG 0 LOGFILE 0 LOGS 0 LONG 1 @@ -314,6 +331,7 @@ LONGBLOB 1 LONGTEXT 1 LOOP 1 LOW_PRIORITY 1 +MANUAL 0 MASTER 0 MASTER_AUTO_POSITION 0 MASTER_BIND 1 @@ -428,7 +446,9 @@ OVER 1 OWNER 0 PACK_KEYS 0 PAGE 0 +PARALLEL 0 PARSER 0 +PARSE_TREE 0 PARTIAL 0 PARTITION 1 PARTITIONING 0 @@ -462,6 +482,7 @@ PROFILE 0 PROFILES 0 PROXY 0 PURGE 1 +QUALIFY 0 QUARTER 0 QUERY 0 QUICK 0 @@ -481,6 +502,7 @@ REDUNDANT 0 REFERENCE 0 REFERENCES 1 REGEXP 1 +REGISTRATION 0 RELAY 0 RELAYLOG 0 RELAY_LOG_FILE 0 @@ -537,6 +559,7 @@ ROW_COUNT 0 ROW_FORMAT 0 ROW_NUMBER 1 RTREE 0 +S3 0 SAVEPOINT 0 SCHEDULE 0 SCHEMA 1 @@ -574,7 +597,33 @@ SOME 0 SONAME 0 SOUNDS 0 SOURCE 0 +SOURCE_AUTO_POSITION 0 +SOURCE_BIND 0 +SOURCE_COMPRESSION_ALGORITHMS 0 SOURCE_CONNECTION_AUTO_FAILOVER 0 +SOURCE_CONNECT_RETRY 0 +SOURCE_DELAY 0 +SOURCE_HEARTBEAT_PERIOD 0 +SOURCE_HOST 0 +SOURCE_LOG_FILE 0 +SOURCE_LOG_POS 0 +SOURCE_PASSWORD 0 +SOURCE_PORT 0 +SOURCE_PUBLIC_KEY_PATH 0 +SOURCE_RETRY_COUNT 0 +SOURCE_SSL 0 +SOURCE_SSL_CA 0 +SOURCE_SSL_CAPATH 0 +SOURCE_SSL_CERT 0 +SOURCE_SSL_CIPHER 0 +SOURCE_SSL_CRL 0 +SOURCE_SSL_CRLPATH 0 +SOURCE_SSL_KEY 0 +SOURCE_SSL_VERIFY_SERVER_CERT 0 +SOURCE_TLS_CIPHERSUITES 0 +SOURCE_TLS_VERSION 0 +SOURCE_USER 0 +SOURCE_ZSTD_COMPRESSION_LEVEL 0 SPATIAL 1 SPECIFIC 1 SQL 1 @@ -625,6 +674,7 @@ SWITCHES 0 SYSTEM 1 TABLE 1 TABLES 0 +TABLESAMPLE 0 TABLESPACE 0 TABLE_CHECKSUM 0 TABLE_NAME 0 @@ -665,10 +715,12 @@ UNION 1 UNIQUE 1 UNKNOWN 0 UNLOCK 1 +UNREGISTER 0 UNSIGNED 1 UNTIL 0 UPDATE 1 UPGRADE 0 +URL 0 USAGE 1 USE 1 USER 0 diff --git a/go/vt/topo/helpers/copy.go b/go/vt/topo/helpers/copy.go index 6dff1c6ac22..94e2d8aca70 100644 --- a/go/vt/topo/helpers/copy.go +++ b/go/vt/topo/helpers/copy.go @@ -41,7 +41,6 @@ func CopyKeyspaces(ctx context.Context, fromTS, toTS *topo.Server, parser *sqlpa } for _, keyspace := range keyspaces { - ki, err := fromTS.GetKeyspace(ctx, keyspace) if err != nil { return fmt.Errorf("GetKeyspace(%v): %w", keyspace, err) @@ -55,15 +54,15 @@ func CopyKeyspaces(ctx context.Context, fromTS, toTS *topo.Server, parser *sqlpa } } - vs, err := fromTS.GetVSchema(ctx, keyspace) + ksvs, err := fromTS.GetVSchema(ctx, keyspace) switch { case err == nil: - _, err = vindexes.BuildKeyspace(vs, parser) + _, err = vindexes.BuildKeyspace(ksvs.Keyspace, parser) if err != nil { log.Errorf("BuildKeyspace(%v): %v", keyspace, err) break } - if err := toTS.SaveVSchema(ctx, keyspace, vs); err != nil { + if err := toTS.SaveVSchema(ctx, ksvs); err != nil { log.Errorf("SaveVSchema(%v): %v", keyspace, err) } case topo.IsErrType(err, topo.NoNode): diff --git a/go/vt/topo/keyspace.go b/go/vt/topo/keyspace.go index 743d8fd6dc0..710bbee0653 100755 --- a/go/vt/topo/keyspace.go +++ b/go/vt/topo/keyspace.go @@ -22,44 +22,26 @@ import ( "sort" "sync" - "github.com/spf13/pflag" "golang.org/x/sync/errgroup" "vitess.io/vitess/go/constants/sidecar" + "vitess.io/vitess/go/event" "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/vt/key" - "vitess.io/vitess/go/vt/servenv" - "vitess.io/vitess/go/vt/vterrors" - - "vitess.io/vitess/go/event" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/topo/events" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo/events" + "vitess.io/vitess/go/vt/vterrors" ) // This file contains keyspace utility functions. -// Default concurrency to use in order to avoid overhwelming the topo server. -var DefaultConcurrency = 32 - // shardKeySuffix is the suffix of a shard key. // The full key looks like this: // /vitess/global/keyspaces/customer/shards/80-/Shard const shardKeySuffix = "Shard" -func registerFlags(fs *pflag.FlagSet) { - fs.IntVar(&DefaultConcurrency, "topo_read_concurrency", DefaultConcurrency, "Concurrency of topo reads.") -} - -func init() { - servenv.OnParseFor("vtcombo", registerFlags) - servenv.OnParseFor("vtctld", registerFlags) - servenv.OnParseFor("vtgate", registerFlags) - servenv.OnParseFor("vtorc", registerFlags) -} - // KeyspaceInfo is a meta struct that contains metadata to give the // data more context and convenience. This is the main way we interact // with a keyspace. @@ -210,7 +192,7 @@ func (ts *Server) UpdateKeyspace(ctx context.Context, ki *KeyspaceInfo) error { type FindAllShardsInKeyspaceOptions struct { // Concurrency controls the maximum number of concurrent calls to GetShard. // If <= 0, Concurrency is set to 1. - Concurrency int + Concurrency int64 } // FindAllShardsInKeyspace reads and returns all the existing shards in a @@ -228,7 +210,7 @@ func (ts *Server) FindAllShardsInKeyspace(ctx context.Context, keyspace string, opt = &FindAllShardsInKeyspaceOptions{} } if opt.Concurrency <= 0 { - opt.Concurrency = DefaultConcurrency + opt.Concurrency = DefaultReadConcurrency } // Unescape the keyspace name as this can e.g. come from the VSchema where diff --git a/go/vt/topo/server.go b/go/vt/topo/server.go index 4a3c2e6bb27..865dbc4bed8 100644 --- a/go/vt/topo/server.go +++ b/go/vt/topo/server.go @@ -49,6 +49,7 @@ import ( "sync" "github.com/spf13/pflag" + "golang.org/x/sync/semaphore" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/proto/topodata" @@ -181,6 +182,9 @@ var ( FlagBinaries = []string{"vttablet", "vtctl", "vtctld", "vtcombo", "vtgate", "vtorc", "vtbackup"} + + // Default read concurrency to use in order to avoid overhwelming the topo server. + DefaultReadConcurrency int64 = 32 ) func init() { @@ -193,6 +197,7 @@ func registerTopoFlags(fs *pflag.FlagSet) { fs.StringVar(&topoImplementation, "topo_implementation", topoImplementation, "the topology implementation to use") fs.StringVar(&topoGlobalServerAddress, "topo_global_server_address", topoGlobalServerAddress, "the address of the global topology server") fs.StringVar(&topoGlobalRoot, "topo_global_root", topoGlobalRoot, "the path of the global topology data in the global topology server") + fs.Int64Var(&DefaultReadConcurrency, "topo_read_concurrency", DefaultReadConcurrency, "Maximum concurrency of topo reads per global or local cell.") } // RegisterFactory registers a Factory for an implementation for a Server. @@ -208,11 +213,12 @@ func RegisterFactory(name string, factory Factory) { // NewWithFactory creates a new Server based on the given Factory. // It also opens the global cell connection. func NewWithFactory(factory Factory, serverAddress, root string) (*Server, error) { + globalReadSem := semaphore.NewWeighted(DefaultReadConcurrency) conn, err := factory.Create(GlobalCell, serverAddress, root) if err != nil { return nil, err } - conn = NewStatsConn(GlobalCell, conn) + conn = NewStatsConn(GlobalCell, conn, globalReadSem) var connReadOnly Conn if factory.HasGlobalReadOnlyCell(serverAddress, root) { @@ -220,7 +226,7 @@ func NewWithFactory(factory Factory, serverAddress, root string) (*Server, error if err != nil { return nil, err } - connReadOnly = NewStatsConn(GlobalReadOnlyCell, connReadOnly) + connReadOnly = NewStatsConn(GlobalReadOnlyCell, connReadOnly, globalReadSem) } else { connReadOnly = conn } @@ -302,7 +308,8 @@ func (ts *Server) ConnForCell(ctx context.Context, cell string) (Conn, error) { conn, err := ts.factory.Create(cell, ci.ServerAddress, ci.Root) switch { case err == nil: - conn = NewStatsConn(cell, conn) + cellReadSem := semaphore.NewWeighted(DefaultReadConcurrency) + conn = NewStatsConn(cell, conn, cellReadSem) ts.cellConns[cell] = cellConn{ci, conn} return conn, nil case IsErrType(err, NoNode): diff --git a/go/vt/topo/shard.go b/go/vt/topo/shard.go index 7df6dc64b88..a610cac885a 100644 --- a/go/vt/topo/shard.go +++ b/go/vt/topo/shard.go @@ -658,16 +658,8 @@ func (ts *Server) GetTabletsByShardCell(ctx context.Context, keyspace, shard str } } - // Divide the concurrency limit by the number of cells. If there are more - // cells than the limit, default to concurrency of 1. - cellConcurrency := 1 - if len(cells) < DefaultConcurrency { - cellConcurrency = DefaultConcurrency / len(cells) - } - mu := sync.Mutex{} eg, ctx := errgroup.WithContext(ctx) - eg.SetLimit(DefaultConcurrency) tablets := make([]*TabletInfo, 0, len(cells)) var kss *KeyspaceShard @@ -678,7 +670,6 @@ func (ts *Server) GetTabletsByShardCell(ctx context.Context, keyspace, shard str } } options := &GetTabletsByCellOptions{ - Concurrency: cellConcurrency, KeyspaceShard: kss, } for _, cell := range cells { diff --git a/go/vt/topo/shard_test.go b/go/vt/topo/shard_test.go index 6bd4aae5b62..915bcd18e3c 100644 --- a/go/vt/topo/shard_test.go +++ b/go/vt/topo/shard_test.go @@ -323,6 +323,14 @@ func TestValidateShardName(t *testing.T) { }, valid: true, }, + { + name: "-", + expectedRange: &topodatapb.KeyRange{ + Start: []byte{}, + End: []byte{}, + }, + valid: true, + }, { name: "40-80", expectedRange: &topodatapb.KeyRange{ diff --git a/go/vt/topo/srv_vschema.go b/go/vt/topo/srv_vschema.go index f69fca83537..e698c4f8851 100644 --- a/go/vt/topo/srv_vschema.go +++ b/go/vt/topo/srv_vschema.go @@ -171,10 +171,13 @@ func (ts *Server) RebuildSrvVSchema(ctx context.Context, cells []string) error { go func(keyspace string) { defer wg.Done() - k, err := ts.GetVSchema(ctx, keyspace) + ksvs, err := ts.GetVSchema(ctx, keyspace) if IsErrType(err, NoNode) { err = nil - k = &vschemapb.Keyspace{} + ksvs = &KeyspaceVSchemaInfo{ + Name: keyspace, + Keyspace: &vschemapb.Keyspace{}, + } } mu.Lock() @@ -184,7 +187,7 @@ func (ts *Server) RebuildSrvVSchema(ctx context.Context, cells []string) error { finalErr = err return } - srvVSchema.Keyspaces[keyspace] = k + srvVSchema.Keyspaces[keyspace] = ksvs.Keyspace }(keyspace) } wg.Wait() diff --git a/go/vt/topo/stats_conn.go b/go/vt/topo/stats_conn.go index 39bc8c9bc43..ded362b9139 100644 --- a/go/vt/topo/stats_conn.go +++ b/go/vt/topo/stats_conn.go @@ -20,6 +20,8 @@ import ( "context" "time" + "golang.org/x/sync/semaphore" + "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" @@ -37,6 +39,11 @@ var ( "TopologyConnErrors", "TopologyConnErrors errors per operation", []string{"Operation", "Cell"}) + + topoStatsConnReadWaitTimings = stats.NewMultiTimings( + "TopologyConnReadWaits", + "TopologyConnReadWait timings", + []string{"Operation", "Cell"}) ) const readOnlyErrorStrFormat = "cannot perform %s on %s as the topology server connection is read-only" @@ -46,14 +53,16 @@ type StatsConn struct { cell string conn Conn readOnly bool + readSem *semaphore.Weighted } // NewStatsConn returns a StatsConn -func NewStatsConn(cell string, conn Conn) *StatsConn { +func NewStatsConn(cell string, conn Conn, readSem *semaphore.Weighted) *StatsConn { return &StatsConn{ cell: cell, conn: conn, readOnly: false, + readSem: readSem, } } @@ -61,6 +70,12 @@ func NewStatsConn(cell string, conn Conn) *StatsConn { func (st *StatsConn) ListDir(ctx context.Context, dirPath string, full bool) ([]DirEntry, error) { startTime := time.Now() statsKey := []string{"ListDir", st.cell} + if err := st.readSem.Acquire(ctx, 1); err != nil { + return nil, err + } + defer st.readSem.Release(1) + topoStatsConnReadWaitTimings.Record(statsKey, startTime) + startTime = time.Now() // reset defer topoStatsConnTimings.Record(statsKey, startTime) res, err := st.conn.ListDir(ctx, dirPath, full) if err != nil { @@ -106,6 +121,12 @@ func (st *StatsConn) Update(ctx context.Context, filePath string, contents []byt func (st *StatsConn) Get(ctx context.Context, filePath string) ([]byte, Version, error) { startTime := time.Now() statsKey := []string{"Get", st.cell} + if err := st.readSem.Acquire(ctx, 1); err != nil { + return nil, nil, err + } + defer st.readSem.Release(1) + topoStatsConnReadWaitTimings.Record(statsKey, startTime) + startTime = time.Now() // reset defer topoStatsConnTimings.Record(statsKey, startTime) bytes, version, err := st.conn.Get(ctx, filePath) if err != nil { @@ -119,6 +140,12 @@ func (st *StatsConn) Get(ctx context.Context, filePath string) ([]byte, Version, func (st *StatsConn) GetVersion(ctx context.Context, filePath string, version int64) ([]byte, error) { startTime := time.Now() statsKey := []string{"GetVersion", st.cell} + if err := st.readSem.Acquire(ctx, 1); err != nil { + return nil, err + } + defer st.readSem.Release(1) + topoStatsConnReadWaitTimings.Record(statsKey, startTime) + startTime = time.Now() // reset defer topoStatsConnTimings.Record(statsKey, startTime) bytes, err := st.conn.GetVersion(ctx, filePath, version) if err != nil { @@ -132,6 +159,12 @@ func (st *StatsConn) GetVersion(ctx context.Context, filePath string, version in func (st *StatsConn) List(ctx context.Context, filePathPrefix string) ([]KVInfo, error) { startTime := time.Now() statsKey := []string{"List", st.cell} + if err := st.readSem.Acquire(ctx, 1); err != nil { + return nil, err + } + defer st.readSem.Release(1) + topoStatsConnReadWaitTimings.Record(statsKey, startTime) + startTime = time.Now() // reset defer topoStatsConnTimings.Record(statsKey, startTime) bytes, err := st.conn.List(ctx, filePathPrefix) if err != nil { diff --git a/go/vt/topo/stats_conn_test.go b/go/vt/topo/stats_conn_test.go index 605487697cc..9e48ec58407 100644 --- a/go/vt/topo/stats_conn_test.go +++ b/go/vt/topo/stats_conn_test.go @@ -23,11 +23,24 @@ import ( "time" "github.com/stretchr/testify/require" + "golang.org/x/sync/semaphore" "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" ) +// testStatsConnReadSem is a semaphore for unit tests. +// It intentionally has a concurrency limit of '1' to +// allow semaphore contention in tests. +var testStatsConnReadSem = semaphore.NewWeighted(1) + +// testStatsConnStatsReset resets StatsConn-based stats. +func testStatsConnStatsReset() { + topoStatsConnErrors.ResetAll() + topoStatsConnReadWaitTimings.Reset() + topoStatsConnTimings.Reset() +} + // The fakeConn is a wrapper for a Conn that emits stats for every operation type fakeConn struct { v Version @@ -181,218 +194,217 @@ func (st *fakeConn) IsReadOnly() bool { return st.readOnly } +// createTestReadSemaphoreContention simulates semaphore contention on the test read semaphore. +func createTestReadSemaphoreContention(ctx context.Context, duration time.Duration, semAcquiredChan chan struct{}) { + if err := testStatsConnReadSem.Acquire(ctx, 1); err != nil { + panic(err) + } + defer testStatsConnReadSem.Release(1) + semAcquiredChan <- struct{}{} + time.Sleep(duration) +} + // TestStatsConnTopoListDir emits stats on ListDir func TestStatsConnTopoListDir(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) ctx := context.Background() + semAcquiredChan := make(chan struct{}) + go createTestReadSemaphoreContention(ctx, 100*time.Millisecond, semAcquiredChan) + <-semAcquiredChan statsConn.ListDir(ctx, "", true) - timingCounts := topoStatsConnTimings.Counts()["ListDir.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["ListDir.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + + require.Equal(t, int64(1), topoStatsConnReadWaitTimings.Counts()["ListDir.global"]) + require.NotZero(t, topoStatsConnReadWaitTimings.Time()) // error is zero before getting an error - errorCount := topoStatsConnErrors.Counts()["ListDir.global"] - if got, want := errorCount, int64(0); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Zero(t, topoStatsConnErrors.Counts()["ListDir.global"]) statsConn.ListDir(ctx, "error", true) // error stats gets emitted - errorCount = topoStatsConnErrors.Counts()["ListDir.global"] - if got, want := errorCount, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnErrors.Counts()["ListDir.global"]) } // TestStatsConnTopoCreate emits stats on Create func TestStatsConnTopoCreate(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) ctx := context.Background() statsConn.Create(ctx, "", []byte{}) - timingCounts := topoStatsConnTimings.Counts()["Create.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["Create.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + require.Zero(t, topoStatsConnReadWaitTimings.Time()) // error is zero before getting an error - errorCount := topoStatsConnErrors.Counts()["Create.global"] - if got, want := errorCount, int64(0); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Zero(t, topoStatsConnErrors.Counts()["Create.global"]) statsConn.Create(ctx, "error", []byte{}) // error stats gets emitted - errorCount = topoStatsConnErrors.Counts()["Create.global"] - if got, want := errorCount, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnErrors.Counts()["Create.global"]) } // TestStatsConnTopoUpdate emits stats on Update func TestStatsConnTopoUpdate(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) ctx := context.Background() statsConn.Update(ctx, "", []byte{}, conn.v) - timingCounts := topoStatsConnTimings.Counts()["Update.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["Update.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + require.Zero(t, topoStatsConnReadWaitTimings.Time()) // error is zero before getting an error - errorCount := topoStatsConnErrors.Counts()["Update.global"] - if got, want := errorCount, int64(0); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Zero(t, topoStatsConnErrors.Counts()["Update.global"]) statsConn.Update(ctx, "error", []byte{}, conn.v) // error stats gets emitted - errorCount = topoStatsConnErrors.Counts()["Update.global"] - if got, want := errorCount, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnErrors.Counts()["Update.global"]) } // TestStatsConnTopoGet emits stats on Get func TestStatsConnTopoGet(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) ctx := context.Background() + semAcquiredChan := make(chan struct{}) + go createTestReadSemaphoreContention(ctx, time.Millisecond*100, semAcquiredChan) + <-semAcquiredChan statsConn.Get(ctx, "") - timingCounts := topoStatsConnTimings.Counts()["Get.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["Get.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + + require.Equal(t, int64(1), topoStatsConnReadWaitTimings.Counts()["Get.global"]) + require.NotZero(t, topoStatsConnReadWaitTimings.Time()) // error is zero before getting an error - errorCount := topoStatsConnErrors.Counts()["Get.global"] - if got, want := errorCount, int64(0); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Zero(t, topoStatsConnErrors.Counts()["Get.global"]) statsConn.Get(ctx, "error") // error stats gets emitted - errorCount = topoStatsConnErrors.Counts()["Get.global"] - if got, want := errorCount, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnErrors.Counts()["Get.global"]) } // TestStatsConnTopoDelete emits stats on Delete func TestStatsConnTopoDelete(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) ctx := context.Background() statsConn.Delete(ctx, "", conn.v) - timingCounts := topoStatsConnTimings.Counts()["Delete.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["Delete.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + require.Zero(t, topoStatsConnReadWaitTimings.Time()) // error is zero before getting an error - errorCount := topoStatsConnErrors.Counts()["Delete.global"] - if got, want := errorCount, int64(0); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Zero(t, topoStatsConnErrors.Counts()["Delete.global"]) statsConn.Delete(ctx, "error", conn.v) // error stats gets emitted - errorCount = topoStatsConnErrors.Counts()["Delete.global"] - if got, want := errorCount, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnErrors.Counts()["Delete.global"]) } // TestStatsConnTopoLock emits stats on Lock func TestStatsConnTopoLock(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) ctx := context.Background() statsConn.Lock(ctx, "", "") - timingCounts := topoStatsConnTimings.Counts()["Lock.global"] - require.Equal(t, timingCounts, int64(1)) + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["Lock.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + require.Zero(t, topoStatsConnReadWaitTimings.Time()) statsConn.LockWithTTL(ctx, "", "", time.Second) - timingCounts = topoStatsConnTimings.Counts()["LockWithTTL.global"] - require.Equal(t, timingCounts, int64(1)) + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["LockWithTTL.global"]) statsConn.LockName(ctx, "", "") - timingCounts = topoStatsConnTimings.Counts()["LockName.global"] - require.Equal(t, timingCounts, int64(1)) + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["LockName.global"]) // Error is zero before getting an error. - errorCount := topoStatsConnErrors.Counts()["Lock.global"] - require.Equal(t, errorCount, int64(0)) + require.Zero(t, topoStatsConnErrors.Counts()["Lock.global"]) statsConn.Lock(ctx, "error", "") // Error stats gets emitted. - errorCount = topoStatsConnErrors.Counts()["Lock.global"] - require.Equal(t, errorCount, int64(1)) + require.Equal(t, int64(1), topoStatsConnErrors.Counts()["Lock.global"]) } // TestStatsConnTopoWatch emits stats on Watch func TestStatsConnTopoWatch(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) ctx := context.Background() statsConn.Watch(ctx, "") - timingCounts := topoStatsConnTimings.Counts()["Watch.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } - + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["Watch.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + require.Zero(t, topoStatsConnReadWaitTimings.Time()) } // TestStatsConnTopoNewLeaderParticipation emits stats on NewLeaderParticipation func TestStatsConnTopoNewLeaderParticipation(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) _, _ = statsConn.NewLeaderParticipation("", "") - timingCounts := topoStatsConnTimings.Counts()["NewLeaderParticipation.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["NewLeaderParticipation.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + require.Zero(t, topoStatsConnReadWaitTimings.Time()) // error is zero before getting an error - errorCount := topoStatsConnErrors.Counts()["NewLeaderParticipation.global"] - if got, want := errorCount, int64(0); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Zero(t, topoStatsConnErrors.Counts()["NewLeaderParticipation.global"]) _, _ = statsConn.NewLeaderParticipation("error", "") // error stats gets emitted - errorCount = topoStatsConnErrors.Counts()["NewLeaderParticipation.global"] - if got, want := errorCount, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnErrors.Counts()["NewLeaderParticipation.global"]) } // TestStatsConnTopoClose emits stats on Close func TestStatsConnTopoClose(t *testing.T) { + testStatsConnStatsReset() + defer testStatsConnStatsReset() + conn := &fakeConn{} - statsConn := NewStatsConn("global", conn) + statsConn := NewStatsConn("global", conn, testStatsConnReadSem) statsConn.Close() - timingCounts := topoStatsConnTimings.Counts()["Close.global"] - if got, want := timingCounts, int64(1); got != want { - t.Errorf("stats were not properly recorded: got = %d, want = %d", got, want) - } + require.Equal(t, int64(1), topoStatsConnTimings.Counts()["Close.global"]) + require.NotZero(t, topoStatsConnTimings.Time()) + require.Zero(t, topoStatsConnReadWaitTimings.Time()) } diff --git a/go/vt/topo/tablet.go b/go/vt/topo/tablet.go index e52e753a36b..f2c9ab81d67 100644 --- a/go/vt/topo/tablet.go +++ b/go/vt/topo/tablet.go @@ -24,21 +24,17 @@ import ( "sync" "time" - "golang.org/x/sync/semaphore" - - "vitess.io/vitess/go/protoutil" - "vitess.io/vitess/go/vt/key" - "vitess.io/vitess/go/event" "vitess.io/vitess/go/netutil" + "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/trace" + "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/topo/events" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vterrors" ) // IsTrivialTypeChange returns if this db type be trivially reassigned @@ -234,8 +230,6 @@ func (ts *Server) GetTabletAliasesByCell(ctx context.Context, cell string) ([]*t // GetTabletsByCellOptions controls the behavior of // Server.FindAllShardsInKeyspace. type GetTabletsByCellOptions struct { - // Concurrency controls the maximum number of concurrent calls to GetTablet. - Concurrency int // KeyspaceShard is the optional keyspace/shard that tablets must match. // An empty shard value will match all shards in the keyspace. KeyspaceShard *KeyspaceShard @@ -497,29 +491,14 @@ func (ts *Server) GetTabletMap(ctx context.Context, tabletAliases []*topodatapb. returnErr error ) - concurrency := DefaultConcurrency - if opt != nil && opt.Concurrency > 0 { - concurrency = opt.Concurrency - } - var sem = semaphore.NewWeighted(int64(concurrency)) - for _, tabletAlias := range tabletAliases { + if tabletAlias == nil { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "nil tablet alias in list") + } wg.Add(1) go func(tabletAlias *topodatapb.TabletAlias) { defer wg.Done() - if err := sem.Acquire(ctx, 1); err != nil { - // Only happens if context is cancelled. - mu.Lock() - defer mu.Unlock() - log.Warningf("%v: %v", tabletAlias, err) - // We only need to set this on the first error. - if returnErr == nil { - returnErr = NewError(PartialResult, tabletAlias.GetCell()) - } - return - } tabletInfo, err := ts.GetTablet(ctx, tabletAlias) - sem.Release(1) mu.Lock() defer mu.Unlock() if err != nil { diff --git a/go/vt/topo/tablet_test.go b/go/vt/topo/tablet_test.go index e659a0d01b9..1c242e8778b 100644 --- a/go/vt/topo/tablet_test.go +++ b/go/vt/topo/tablet_test.go @@ -69,7 +69,6 @@ func TestServerGetTabletsByCell(t *testing.T) { }, }, // Ensure this doesn't panic. - opt: &topo.GetTabletsByCellOptions{Concurrency: -1}, }, { name: "single", @@ -151,7 +150,6 @@ func TestServerGetTabletsByCell(t *testing.T) { Shard: shard, }, }, - opt: &topo.GetTabletsByCellOptions{Concurrency: 8}, }, { name: "multiple with list error", @@ -210,7 +208,6 @@ func TestServerGetTabletsByCell(t *testing.T) { Shard: shard, }, }, - opt: &topo.GetTabletsByCellOptions{Concurrency: 8}, listError: topo.NewError(topo.ResourceExhausted, ""), }, { @@ -249,7 +246,6 @@ func TestServerGetTabletsByCell(t *testing.T) { }, }, opt: &topo.GetTabletsByCellOptions{ - Concurrency: 1, KeyspaceShard: &topo.KeyspaceShard{ Keyspace: keyspace, Shard: shard, @@ -317,7 +313,6 @@ func TestServerGetTabletsByCell(t *testing.T) { }, }, opt: &topo.GetTabletsByCellOptions{ - Concurrency: 1, KeyspaceShard: &topo.KeyspaceShard{ Keyspace: keyspace, Shard: "", diff --git a/go/vt/topo/test/vschema.go b/go/vt/topo/test/vschema.go index 5063addaefd..384e777ac38 100644 --- a/go/vt/topo/test/vschema.go +++ b/go/vt/topo/test/vschema.go @@ -44,9 +44,12 @@ func checkVSchema(t *testing.T, ctx context.Context, ts *topo.Server) { t.Error(err) } - err = ts.SaveVSchema(ctx, "test_keyspace", &vschemapb.Keyspace{ - Tables: map[string]*vschemapb.Table{ - "unsharded": {}, + err = ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "test_keyspace", + Keyspace: &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "unsharded": {}, + }, }, }) if err != nil { @@ -64,8 +67,11 @@ func checkVSchema(t *testing.T, ctx context.Context, ts *topo.Server) { t.Errorf("GetVSchema: %s, want %s", got, want) } - err = ts.SaveVSchema(ctx, "test_keyspace", &vschemapb.Keyspace{ - Sharded: true, + err = ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "test_keyspace", + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + }, }) require.NoError(t, err) diff --git a/go/vt/topo/topotests/srv_vschema_test.go b/go/vt/topo/topotests/srv_vschema_test.go index 8fd818150b0..fda3582527a 100644 --- a/go/vt/topo/topotests/srv_vschema_test.go +++ b/go/vt/topo/topotests/srv_vschema_test.go @@ -21,6 +21,7 @@ import ( "google.golang.org/protobuf/proto" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -76,7 +77,10 @@ func TestRebuildVSchema(t *testing.T) { keyspace1 := &vschemapb.Keyspace{ Sharded: true, } - if err := ts.SaveVSchema(ctx, "ks1", keyspace1); err != nil { + if err := ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks1", + Keyspace: keyspace1, + }); err != nil { t.Fatalf("SaveVSchema(ks1) failed: %v", err) } if err := ts.RebuildSrvVSchema(ctx, cells); err != nil { @@ -118,7 +122,10 @@ func TestRebuildVSchema(t *testing.T) { }, }, } - if err := ts.SaveVSchema(ctx, "ks2", keyspace2); err != nil { + if err := ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks2", + Keyspace: keyspace2, + }); err != nil { t.Fatalf("SaveVSchema(ks1) failed: %v", err) } if err := ts.RebuildSrvVSchema(ctx, []string{"cell1"}); err != nil { @@ -182,7 +189,10 @@ func TestRebuildVSchema(t *testing.T) { wanted4.RoutingRules = rr // Delete a keyspace, checks vschema entry in map goes away. - if err := ts.SaveVSchema(ctx, "ks2", &vschemapb.Keyspace{}); err != nil { + if err := ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks2", + Keyspace: &vschemapb.Keyspace{}, + }); err != nil { t.Fatalf("SaveVSchema(ks1) failed: %v", err) } if err := ts.DeleteKeyspace(ctx, "ks2"); err != nil { diff --git a/go/vt/topo/vschema.go b/go/vt/topo/vschema.go index 21192e1aacb..9fbf646a74e 100644 --- a/go/vt/topo/vschema.go +++ b/go/vt/topo/vschema.go @@ -20,34 +20,58 @@ import ( "context" "path" - "google.golang.org/protobuf/proto" - "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/vterrors" vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) -// SaveVSchema saves a Vschema. A valid Vschema should be passed in. It does not verify its correctness. -// If the VSchema is empty, just remove it. -func (ts *Server) SaveVSchema(ctx context.Context, keyspace string, vschema *vschemapb.Keyspace) error { +// KeyspaceVSchemaInfo wraps a vschemapb.Keyspace and is a meta +// struct that contains metadata to give the data more context +// and convenience. This is the main way we interact with a +// keyspace's vschema. +type KeyspaceVSchemaInfo struct { + Name string + *vschemapb.Keyspace + version Version +} + +func (k *KeyspaceVSchemaInfo) CloneVT() *KeyspaceVSchemaInfo { + if k == nil { + return (*KeyspaceVSchemaInfo)(nil) + } + kc := &KeyspaceVSchemaInfo{ + Name: k.Name, + version: Version(k.version), + } + if k.Keyspace != nil { + kc.Keyspace = k.Keyspace.CloneVT() + } + return kc +} + +// SaveVSchema saves a Vschema. A valid Vschema should be passed in. +// It does not verify its correctness beyond marshaling it. +func (ts *Server) SaveVSchema(ctx context.Context, ksvs *KeyspaceVSchemaInfo) error { if err := ctx.Err(); err != nil { return err } - nodePath := path.Join(KeyspacesPath, keyspace, VSchemaFile) - data, err := vschema.MarshalVT() + nodePath := path.Join(KeyspacesPath, ksvs.Name, VSchemaFile) + data, err := ksvs.MarshalVT() if err != nil { return err } - _, err = ts.globalCell.Update(ctx, nodePath, data, nil) + version, err := ts.globalCell.Update(ctx, nodePath, data, ksvs.version) if err != nil { - log.Errorf("failed to update vschema for keyspace %s: %v", keyspace, err) - } else { - log.Infof("successfully updated vschema for keyspace %s: %+v", keyspace, vschema) + log.Errorf("failed to update vschema for keyspace %s: %v", ksvs.Name, err) + return err } - return err + ksvs.version = version + log.Infof("successfully updated vschema for keyspace %s: %+v", ksvs.Name, ksvs.Keyspace) + + return nil } // DeleteVSchema delete the keyspace if it exists @@ -61,35 +85,43 @@ func (ts *Server) DeleteVSchema(ctx context.Context, keyspace string) error { } // GetVSchema fetches the vschema from the topo. -func (ts *Server) GetVSchema(ctx context.Context, keyspace string) (*vschemapb.Keyspace, error) { +func (ts *Server) GetVSchema(ctx context.Context, keyspace string) (*KeyspaceVSchemaInfo, error) { if err := ctx.Err(); err != nil { return nil, err } nodePath := path.Join(KeyspacesPath, keyspace, VSchemaFile) - data, _, err := ts.globalCell.Get(ctx, nodePath) + data, version, err := ts.globalCell.Get(ctx, nodePath) if err != nil { return nil, err } - var vs vschemapb.Keyspace - err = proto.Unmarshal(data, &vs) + + vs := &vschemapb.Keyspace{} + err = vs.UnmarshalVT(data) if err != nil { return nil, vterrors.Wrapf(err, "bad vschema data: %q", data) } - return &vs, nil + return &KeyspaceVSchemaInfo{ + Name: keyspace, + Keyspace: vs, + version: version, + }, nil } // EnsureVSchema makes sure that a vschema is present for this keyspace or creates a blank one if it is missing func (ts *Server) EnsureVSchema(ctx context.Context, keyspace string) error { - vschema, err := ts.GetVSchema(ctx, keyspace) + ksvs, err := ts.GetVSchema(ctx, keyspace) if err != nil && !IsErrType(err, NoNode) { log.Infof("error in getting vschema for keyspace %s: %v", keyspace, err) } - if vschema == nil || IsErrType(err, NoNode) { - err = ts.SaveVSchema(ctx, keyspace, &vschemapb.Keyspace{ - Sharded: false, - Vindexes: make(map[string]*vschemapb.Vindex), - Tables: make(map[string]*vschemapb.Table), + if ksvs == nil || ksvs.Keyspace == nil || IsErrType(err, NoNode) { + err = ts.SaveVSchema(ctx, &KeyspaceVSchemaInfo{ + Name: keyspace, + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + Vindexes: make(map[string]*vschemapb.Vindex), + Tables: make(map[string]*vschemapb.Table), + }, }) if err != nil { log.Errorf("could not create blank vschema: %v", err) diff --git a/go/vt/topotools/vschema_ddl.go b/go/vt/topotools/vschema_ddl.go index 3c6f5bced3c..950ea9ed2e6 100644 --- a/go/vt/topotools/vschema_ddl.go +++ b/go/vt/topotools/vschema_ddl.go @@ -17,9 +17,11 @@ limitations under the License. package topotools import ( + "context" "reflect" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" vschemapb "vitess.io/vitess/go/vt/proto/vschema" @@ -28,55 +30,67 @@ import ( // ApplyVSchemaDDL applies the given DDL statement to the vschema // keyspace definition and returns the modified keyspace object. -func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlparser.AlterVschema) (*vschemapb.Keyspace, error) { - if ks == nil { - ks = new(vschemapb.Keyspace) +func ApplyVSchemaDDL(ctx context.Context, ksName string, topoServer *topo.Server, alterVschema *sqlparser.AlterVschema) (*topo.KeyspaceVSchemaInfo, error) { + if topoServer == nil { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot update VSchema as the topology server connection is read-only") + } + // Get the most recent version, which we'll then update. + ksvs, err := topoServer.GetVSchema(ctx, ksName) + if err != nil { + if topo.IsErrType(err, topo.NoNode) { + ksvs = &topo.KeyspaceVSchemaInfo{ + Name: ksName, + Keyspace: &vschemapb.Keyspace{}, + } + } else { + return nil, vterrors.Wrapf(err, "failed to get the current VSchema for the %s keyspace", ksName) + } } - if ks.Tables == nil { - ks.Tables = map[string]*vschemapb.Table{} + if ksvs.Tables == nil { + ksvs.Tables = map[string]*vschemapb.Table{} } - if ks.Vindexes == nil { - ks.Vindexes = map[string]*vschemapb.Vindex{} + if ksvs.Vindexes == nil { + ksvs.Vindexes = map[string]*vschemapb.Vindex{} } var tableName string var table *vschemapb.Table if !alterVschema.Table.IsEmpty() { tableName = alterVschema.Table.Name.String() - table = ks.Tables[tableName] + table = ksvs.Tables[tableName] } switch alterVschema.Action { case sqlparser.CreateVindexDDLAction: name := alterVschema.VindexSpec.Name.String() - if _, ok := ks.Vindexes[name]; ok { + if _, ok := ksvs.Vindexes[name]; ok { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex %s already exists in keyspace %s", name, ksName) } // Make sure the keyspace has the sharded bit set to true // if this is the first vindex defined in the keyspace. - if len(ks.Vindexes) == 0 { - ks.Sharded = true + if len(ksvs.Vindexes) == 0 { + ksvs.Sharded = true } owner, params := alterVschema.VindexSpec.ParseParams() - ks.Vindexes[name] = &vschemapb.Vindex{ + ksvs.Vindexes[name] = &vschemapb.Vindex{ Type: alterVschema.VindexSpec.Type.String(), Params: params, Owner: owner, } - return ks, nil + return ksvs, nil case sqlparser.DropVindexDDLAction: name := alterVschema.VindexSpec.Name.String() - if _, ok := ks.Vindexes[name]; !ok { + if _, ok := ksvs.Vindexes[name]; !ok { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex %s does not exists in keyspace %s", name, ksName) } - for tableName, table := range ks.Tables { + for tableName, table := range ksvs.Tables { // Make sure there isn't a vindex with the same name left on the table. for _, vindex := range table.ColumnVindexes { if vindex.Name == name { @@ -85,33 +99,33 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar } } - delete(ks.Vindexes, name) + delete(ksvs.Vindexes, name) - return ks, nil + return ksvs, nil case sqlparser.AddVschemaTableDDLAction: - if ks.Sharded { + if ksvs.Sharded { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "add vschema table: unsupported on sharded keyspace %s", ksName) } name := alterVschema.Table.Name.String() - if _, ok := ks.Tables[name]; ok { + if _, ok := ksvs.Tables[name]; ok { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vschema already contains table %s in keyspace %s", name, ksName) } - ks.Tables[name] = &vschemapb.Table{} + ksvs.Tables[name] = &vschemapb.Table{} - return ks, nil + return ksvs, nil case sqlparser.DropVschemaTableDDLAction: name := alterVschema.Table.Name.String() - if _, ok := ks.Tables[name]; !ok { + if _, ok := ksvs.Tables[name]; !ok { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vschema does not contain table %s in keyspace %s", name, ksName) } - delete(ks.Tables, name) + delete(ksvs.Tables, name) - return ks, nil + return ksvs, nil case sqlparser.AddColVindexDDLAction: // Support two cases: @@ -126,7 +140,7 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar name := spec.Name.String() if spec.Type.NotEmpty() { owner, params := spec.ParseParams() - if vindex, ok := ks.Vindexes[name]; ok { + if vindex, ok := ksvs.Vindexes[name]; ok { if vindex.Type != spec.Type.String() { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex %s defined with type %s not %s", name, vindex.Type, spec.Type.String()) } @@ -139,17 +153,17 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar } else { // Make sure the keyspace has the sharded bit set to true // if this is the first vindex defined in the keyspace. - if len(ks.Vindexes) == 0 { - ks.Sharded = true + if len(ksvs.Vindexes) == 0 { + ksvs.Sharded = true } - ks.Vindexes[name] = &vschemapb.Vindex{ + ksvs.Vindexes[name] = &vschemapb.Vindex{ Type: spec.Type.String(), Params: params, Owner: owner, } } } else { - if _, ok := ks.Vindexes[name]; !ok { + if _, ok := ksvs.Vindexes[name]; !ok { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex %s does not exist in keyspace %s", name, ksName) } } @@ -178,9 +192,9 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar Name: name, Columns: columns, }) - ks.Tables[tableName] = table + ksvs.Tables[tableName] = table - return ks, nil + return ksvs, nil case sqlparser.DropColVindexDDLAction: spec := alterVschema.VindexSpec @@ -193,44 +207,44 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar if colVindex.Name == name { table.ColumnVindexes = append(table.ColumnVindexes[:i], table.ColumnVindexes[i+1:]...) if len(table.ColumnVindexes) == 0 { - delete(ks.Tables, tableName) + delete(ksvs.Tables, tableName) } - return ks, nil + return ksvs, nil } } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex %s not defined in table %s.%s", name, ksName, tableName) case sqlparser.AddSequenceDDLAction: - if ks.Sharded { + if ksvs.Sharded { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "add sequence table: unsupported on sharded keyspace %s", ksName) } name := alterVschema.Table.Name.String() - if _, ok := ks.Tables[name]; ok { + if _, ok := ksvs.Tables[name]; ok { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vschema already contains sequence %s in keyspace %s", name, ksName) } - ks.Tables[name] = &vschemapb.Table{Type: "sequence"} + ksvs.Tables[name] = &vschemapb.Table{Type: "sequence"} - return ks, nil + return ksvs, nil case sqlparser.DropSequenceDDLAction: - if ks.Sharded { + if ksvs.Sharded { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "drop sequence table: unsupported on sharded keyspace %s", ksName) } name := alterVschema.Table.Name.String() - if _, ok := ks.Tables[name]; !ok { + if _, ok := ksvs.Tables[name]; !ok { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vschema does not contain sequence %s in keyspace %s", name, ksName) } - delete(ks.Tables, name) + delete(ksvs.Tables, name) - return ks, nil + return ksvs, nil case sqlparser.AddAutoIncDDLAction: name := alterVschema.Table.Name.String() - table := ks.Tables[name] + table := ksvs.Tables[name] if table == nil { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vschema does not contain table %s in keyspace %s", name, ksName) } @@ -244,11 +258,11 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar Sequence: sqlparser.String(alterVschema.AutoIncSpec.Sequence), } - return ks, nil + return ksvs, nil case sqlparser.DropAutoIncDDLAction: name := alterVschema.Table.Name.String() - table := ks.Tables[name] + table := ksvs.Tables[name] if table == nil { return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vschema does not contain table %s in keyspace %s", name, ksName) } @@ -259,7 +273,7 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar table.AutoIncrement = nil - return ks, nil + return ksvs, nil } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected vindex ddl operation %s", alterVschema.Action.ToString()) diff --git a/go/vt/vitessdriver/convert.go b/go/vt/vitessdriver/convert.go index aa8bcedc7ee..c5141d1c890 100644 --- a/go/vt/vitessdriver/convert.go +++ b/go/vt/vitessdriver/convert.go @@ -18,9 +18,11 @@ package vitessdriver import ( "database/sql/driver" + "errors" "fmt" "time" + "vitess.io/vitess/go/mysql/datetime" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" @@ -43,8 +45,10 @@ func (cv *converter) ToNative(v sqltypes.Value) (any, error) { return v.ToUint64() case v.IsFloat(): return v.ToFloat64() - case v.Type() == sqltypes.Datetime, v.Type() == sqltypes.Timestamp, v.Type() == sqltypes.Date: - return v.ToTimeInLocation(cv.location) + case v.Type() == sqltypes.Datetime, v.Type() == sqltypes.Timestamp: + return cv.datetimeToTime(v) + case v.Type() == sqltypes.Date: + return cv.dateToTime(v) case v.IsQuoted() || v.Type() == sqltypes.Bit || v.Type() == sqltypes.Decimal: out, err = v.ToBytes() case v.Type() == sqltypes.Expression: @@ -53,6 +57,56 @@ func (cv *converter) ToNative(v sqltypes.Value) (any, error) { return out, err } +// ErrInvalidTime is returned when we fail to parse a datetime +// string from MySQL. This should never happen unless things are +// seriously messed up. +var ErrInvalidTime = errors.New("invalid MySQL time string") + +func (cv *converter) datetimeToTime(v sqltypes.Value) (time.Time, error) { + if v.IsNull() { + return time.Time{}, nil + } + // Valid format string offsets for a DATETIME + // |DATETIME |19+ + // |------------------|------| + // "2006-01-02 15:04:05.999999" + dt, _, ok := datetime.ParseDateTime(v.ToString(), -1) + if !ok { + return time.Time{}, ErrInvalidTime + } + if dt.IsZero() { + return time.Time{}, nil + } + loc := cv.location + if loc == nil { + loc = time.UTC + } + return time.Date(dt.Date.Year(), time.Month(dt.Date.Month()), dt.Date.Day(), + dt.Time.Hour(), dt.Time.Minute(), dt.Time.Second(), dt.Time.Nanosecond(), loc), nil +} + +func (cv *converter) dateToTime(v sqltypes.Value) (time.Time, error) { + if v.IsNull() { + return time.Time{}, nil + } + // Valid format string offsets for a DATE + // |DATE |10 + // |---------| + // "2006-01-02 00:00:00.000000" + d, ok := datetime.ParseDate(v.ToString()) + if !ok { + return time.Time{}, ErrInvalidTime + } + if d.IsZero() { + return time.Time{}, nil + } + loc := cv.location + if loc == nil { + loc = time.UTC + } + return time.Date(d.Year(), time.Month(d.Month()), d.Day(), 0, 0, 0, 0, loc), nil +} + func (cv *converter) BuildBindVariable(v any) (*querypb.BindVariable, error) { if t, ok := v.(time.Time); ok { return sqltypes.ValueBindVariable(NewDatetime(t, cv.location)), nil diff --git a/go/vt/vtadmin/api.go b/go/vt/vtadmin/api.go index 4f91459d9ed..a54090bb044 100644 --- a/go/vt/vtadmin/api.go +++ b/go/vt/vtadmin/api.go @@ -1785,7 +1785,7 @@ func (api *API) VDiffShow(ctx context.Context, req *vtadminpb.VDiffShowRequest) } } if report.State == string(vdiff.StartedState) { - progress := vdiffcmd.BuildProgressReport(report.RowsCompared, totalRowsToCompare, report.StartedAt) + progress := workflow.BuildProgressReport(report.RowsCompared, totalRowsToCompare, report.StartedAt) report.Progress = &vtadminpb.VDiffProgress{ Percentage: progress.Percentage, Eta: progress.ETA, diff --git a/go/vt/vtadmin/cluster/cluster.go b/go/vt/vtadmin/cluster/cluster.go index bdc9272a92f..1fc6494ddfa 100644 --- a/go/vt/vtadmin/cluster/cluster.go +++ b/go/vt/vtadmin/cluster/cluster.go @@ -1443,7 +1443,7 @@ func (c *Cluster) GetSchema(ctx context.Context, keyspace string, opts GetSchema return nil, err } - go schemacache.AddOrBackfill(c.schemaCache, []*vtadminpb.Schema{schema}, key, cache.DefaultExpiration, schemacache.LoadOptions{ + go schemacache.AddOrBackfill(c.schemaCache, []*vtadminpb.Schema{schema}, key, c.cfg.SchemaCacheConfig.DefaultExpiration, schemacache.LoadOptions{ BaseRequest: opts.BaseRequest, AggregateSizes: opts.TableSizeOptions.AggregateSizes, }) @@ -1604,7 +1604,7 @@ func (c *Cluster) GetSchemas(ctx context.Context, opts GetSchemaOptions) ([]*vta return nil, rec.Error() } - go schemacache.AddOrBackfill(c.schemaCache, schemas, key, cache.DefaultExpiration, schemacache.LoadOptions{ + go schemacache.AddOrBackfill(c.schemaCache, schemas, key, c.cfg.SchemaCacheConfig.DefaultExpiration, schemacache.LoadOptions{ BaseRequest: opts.BaseRequest, AggregateSizes: opts.TableSizeOptions.AggregateSizes, }) diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index fc02409bd5f..64b49ae2bed 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -410,7 +410,11 @@ func CreateKs( if err != nil { return 0, fmt.Errorf("BuildKeyspace(%v) failed: %v", keyspace, err) } - if err := ts.SaveVSchema(ctx, keyspace, formal); err != nil { + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: keyspace, + Keyspace: formal, + } + if err := ts.SaveVSchema(ctx, ksvs); err != nil { return 0, fmt.Errorf("SaveVSchema(%v) failed: %v", keyspace, err) } } else { diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index c2da0e97c54..368c0573bd7 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -173,6 +173,15 @@ func (client *gRPCVtctldClient) ConcludeTransaction(ctx context.Context, in *vtc return client.c.ConcludeTransaction(ctx, in, opts...) } +// CopySchemaShard is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) CopySchemaShard(ctx context.Context, in *vtctldatapb.CopySchemaShardRequest, opts ...grpc.CallOption) (*vtctldatapb.CopySchemaShardResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.CopySchemaShard(ctx, in, opts...) +} + // CreateKeyspace is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) CreateKeyspace(ctx context.Context, in *vtctldatapb.CreateKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.CreateKeyspaceResponse, error) { if client.c == nil { @@ -587,6 +596,15 @@ func (client *gRPCVtctldClient) LaunchSchemaMigration(ctx context.Context, in *v return client.c.LaunchSchemaMigration(ctx, in, opts...) } +// LookupVindexComplete is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) LookupVindexComplete(ctx context.Context, in *vtctldatapb.LookupVindexCompleteRequest, opts ...grpc.CallOption) (*vtctldatapb.LookupVindexCompleteResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.LookupVindexComplete(ctx, in, opts...) +} + // LookupVindexCreate is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) LookupVindexCreate(ctx context.Context, in *vtctldatapb.LookupVindexCreateRequest, opts ...grpc.CallOption) (*vtctldatapb.LookupVindexCreateResponse, error) { if client.c == nil { @@ -605,6 +623,15 @@ func (client *gRPCVtctldClient) LookupVindexExternalize(ctx context.Context, in return client.c.LookupVindexExternalize(ctx, in, opts...) } +// LookupVindexInternalize is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) LookupVindexInternalize(ctx context.Context, in *vtctldatapb.LookupVindexInternalizeRequest, opts ...grpc.CallOption) (*vtctldatapb.LookupVindexInternalizeResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.LookupVindexInternalize(ctx, in, opts...) +} + // MaterializeCreate is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) MaterializeCreate(ctx context.Context, in *vtctldatapb.MaterializeCreateRequest, opts ...grpc.CallOption) (*vtctldatapb.MaterializeCreateResponse, error) { if client.c == nil { @@ -1046,6 +1073,15 @@ func (client *gRPCVtctldClient) ValidateKeyspace(ctx context.Context, in *vtctld return client.c.ValidateKeyspace(ctx, in, opts...) } +// ValidatePermissionsKeyspace is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) ValidatePermissionsKeyspace(ctx context.Context, in *vtctldatapb.ValidatePermissionsKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.ValidatePermissionsKeyspaceResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.ValidatePermissionsKeyspace(ctx, in, opts...) +} + // ValidateSchemaKeyspace is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) ValidateSchemaKeyspace(ctx context.Context, in *vtctldatapb.ValidateSchemaKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.ValidateSchemaKeyspaceResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index bf984a5cd33..7158c575363 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -71,6 +71,7 @@ import ( "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/topotools/events" "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtctl/schematools" "vitess.io/vitess/go/vt/vtctl/workflow" "vitess.io/vitess/go/vt/vtenv" @@ -338,7 +339,9 @@ func (s *VtctldServer) ApplyVSchema(ctx context.Context, req *vtctldatapb.ApplyV return nil, err } - var vs *vschemapb.Keyspace + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: req.Keyspace, + } if req.Sql != "" { span.Annotate("sql_mode", true) @@ -355,29 +358,23 @@ func (s *VtctldServer) ApplyVSchema(ctx context.Context, req *vtctldatapb.ApplyV return nil, err } - vs, err = s.ts.GetVSchema(ctx, req.Keyspace) - if err != nil && !topo.IsErrType(err, topo.NoNode) { - err = vterrors.Wrapf(err, "GetVSchema(%s)", req.Keyspace) - return nil, err - } // otherwise, we keep the empty vschema object from above - - vs, err = topotools.ApplyVSchemaDDL(req.Keyspace, vs, ddl) + ksvs, err = topotools.ApplyVSchemaDDL(ctx, req.Keyspace, s.ts, ddl) if err != nil { - err = vterrors.Wrapf(err, "ApplyVSchemaDDL(%s,%v,%v)", req.Keyspace, vs, ddl) + err = vterrors.Wrapf(err, "ApplyVSchemaDDL(%s,%v,%v)", req.Keyspace, ksvs, ddl) return nil, err } } else { // "jsonMode" span.Annotate("sql_mode", false) - vs = req.VSchema + ksvs.Keyspace = req.VSchema } - ksVs, err := vindexes.BuildKeyspace(vs, s.ws.SQLParser()) + ksVs, err := vindexes.BuildKeyspace(ksvs.Keyspace, s.ws.SQLParser()) if err != nil { err = vterrors.Wrapf(err, "BuildKeyspace(%s)", req.Keyspace) return nil, err } response := &vtctldatapb.ApplyVSchemaResponse{ - VSchema: vs, + VSchema: ksvs.Keyspace, UnknownVindexParams: make(map[string]*vtctldatapb.ApplyVSchemaResponse_ParamList), } @@ -409,7 +406,7 @@ func (s *VtctldServer) ApplyVSchema(ctx context.Context, req *vtctldatapb.ApplyV return response, err } - if err = s.ts.SaveVSchema(ctx, req.Keyspace, vs); err != nil { + if err = s.ts.SaveVSchema(ctx, ksvs); err != nil { err = vterrors.Wrapf(err, "SaveVSchema(%s, %v)", req.Keyspace, req.VSchema) return nil, err } @@ -425,7 +422,7 @@ func (s *VtctldServer) ApplyVSchema(ctx context.Context, req *vtctldatapb.ApplyV err = vterrors.Wrapf(err, "GetVSchema(%s)", req.Keyspace) return nil, err } - response.VSchema = updatedVS + response.VSchema = updatedVS.Keyspace return response, nil } @@ -668,7 +665,7 @@ func (s *VtctldServer) ChangeTabletType(ctx context.Context, req *vtctldatapb.Ch return nil, err } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return nil, err } @@ -698,7 +695,7 @@ func (s *VtctldServer) ChangeTabletType(ctx context.Context, req *vtctldatapb.Ch // Since we want to check the durability rules for the desired state and not before we make that change expectedTablet := tablet.Tablet.CloneVT() expectedTablet.Type = req.DbType - err = s.tmc.ChangeType(ctx, tablet.Tablet, req.DbType, reparentutil.IsReplicaSemiSync(durability, shardPrimary.Tablet, expectedTablet)) + err = s.tmc.ChangeType(ctx, tablet.Tablet, req.DbType, policy.IsReplicaSemiSync(durability, shardPrimary.Tablet, expectedTablet)) if err != nil { return nil, err } @@ -869,6 +866,28 @@ func (s *VtctldServer) CompleteSchemaMigration(ctx context.Context, req *vtctlda return resp, nil } +// CopySchemaShard is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) CopySchemaShard(ctx context.Context, req *vtctldatapb.CopySchemaShardRequest) (resp *vtctldatapb.CopySchemaShardResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.CompleteSchemaMigration") + defer span.Finish() + + defer panicHandler(&err) + + span.Annotate("source_tablet_alias", req.SourceTabletAlias) + span.Annotate("destination_keyspace", req.DestinationKeyspace) + span.Annotate("destination_shard", req.DestinationShard) + + waitReplicasTimeout, _, err := protoutil.DurationFromProto(req.WaitReplicasTimeout) + if err != nil { + return nil, err + } + + err = s.ws.CopySchemaShard(ctx, req.SourceTabletAlias, req.Tables, req.ExcludeTables, req.IncludeViews, + req.DestinationKeyspace, req.DestinationShard, waitReplicasTimeout, req.SkipVerify) + + return &vtctldatapb.CopySchemaShardResponse{}, err +} + // CreateKeyspace is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) CreateKeyspace(ctx context.Context, req *vtctldatapb.CreateKeyspaceRequest) (resp *vtctldatapb.CreateKeyspaceResponse, err error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.CreateKeyspace") @@ -933,28 +952,37 @@ func (s *VtctldServer) CreateKeyspace(ctx context.Context, req *vtctldatapb.Crea } if req.Type == topodatapb.KeyspaceType_SNAPSHOT { - var vs *vschemapb.Keyspace - vs, err = s.ts.GetVSchema(ctx, req.BaseKeyspace) + bksvs, err := s.ts.GetVSchema(ctx, req.BaseKeyspace) if err != nil { log.Infof("error from GetVSchema(%v) = %v", req.BaseKeyspace, err) if topo.IsErrType(err, topo.NoNode) { log.Infof("base keyspace %v does not exist; continuing with bare, unsharded vschema", req.BaseKeyspace) - vs = &vschemapb.Keyspace{ - Sharded: false, - Tables: map[string]*vschemapb.Table{}, - Vindexes: map[string]*vschemapb.Vindex{}, + bksvs = &topo.KeyspaceVSchemaInfo{ + Name: req.Name, + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + Tables: map[string]*vschemapb.Table{}, + Vindexes: map[string]*vschemapb.Vindex{}, + }, } } else { return nil, err } } + // We don't want to clone the base keyspace's key version + // so we do NOT call bksvs.CloneVT() here. We instead only + // clone the vschemapb.Keyspace field for the new snapshot + // keyspace. + sksvs := &topo.KeyspaceVSchemaInfo{ + Name: req.Name, + Keyspace: bksvs.Keyspace.CloneVT(), + } // SNAPSHOT keyspaces are excluded from global routing. - vs.RequireExplicitRouting = true + sksvs.RequireExplicitRouting = true - if err = s.ts.SaveVSchema(ctx, req.Name, vs); err != nil { - err = fmt.Errorf("SaveVSchema(%v) = %w", vs, err) - return nil, err + if err = s.ts.SaveVSchema(ctx, sksvs); err != nil { + return nil, fmt.Errorf("SaveVSchema(%v) = %w", sksvs, err) } } @@ -2646,13 +2674,13 @@ func (s *VtctldServer) GetVSchema(ctx context.Context, req *vtctldatapb.GetVSche span.Annotate("keyspace", req.Keyspace) - vschema, err := s.ts.GetVSchema(ctx, req.Keyspace) + ks, err := s.ts.GetVSchema(ctx, req.Keyspace) if err != nil { return nil, err } return &vtctldatapb.GetVSchemaResponse{ - VSchema: vschema, + VSchema: ks.Keyspace, }, nil } @@ -2766,7 +2794,7 @@ func (s *VtctldServer) InitShardPrimaryLocked( return err } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return err } @@ -2850,7 +2878,7 @@ func (s *VtctldServer) InitShardPrimaryLocked( // position logger.Infof("initializing primary on %v", topoproto.TabletAliasString(req.PrimaryElectTabletAlias)) event.DispatchUpdate(ev, "initializing primary") - rp, err := tmc.InitPrimary(ctx, primaryElectTabletInfo.Tablet, reparentutil.SemiSyncAckers(durability, primaryElectTabletInfo.Tablet) > 0) + rp, err := tmc.InitPrimary(ctx, primaryElectTabletInfo.Tablet, policy.SemiSyncAckers(durability, primaryElectTabletInfo.Tablet) > 0) if err != nil { return err } @@ -2891,7 +2919,7 @@ func (s *VtctldServer) InitShardPrimaryLocked( go func(alias string, tabletInfo *topo.TabletInfo) { defer wgReplicas.Done() logger.Infof("initializing replica %v", alias) - if err := tmc.InitReplica(replCtx, tabletInfo.Tablet, req.PrimaryElectTabletAlias, rp, now, reparentutil.IsReplicaSemiSync(durability, primaryElectTabletInfo.Tablet, tabletInfo.Tablet)); err != nil { + if err := tmc.InitReplica(replCtx, tabletInfo.Tablet, req.PrimaryElectTabletAlias, rp, now, policy.IsReplicaSemiSync(durability, primaryElectTabletInfo.Tablet, tabletInfo.Tablet)); err != nil { rec.RecordError(fmt.Errorf("tablet %v InitReplica failed: %v", alias, err)) } }(alias, tabletInfo) @@ -2980,6 +3008,21 @@ func (s *VtctldServer) LaunchSchemaMigration(ctx context.Context, req *vtctldata return resp, nil } +// LookupVindexComplete is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) LookupVindexComplete(ctx context.Context, req *vtctldatapb.LookupVindexCompleteRequest) (resp *vtctldatapb.LookupVindexCompleteResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.LookupVindexComplete") + defer span.Finish() + + defer panicHandler(&err) + + span.Annotate("name", req.Name) + span.Annotate("keyspace", req.Keyspace) + span.Annotate("table_keyspace", req.TableKeyspace) + + resp, err = s.ws.LookupVindexComplete(ctx, req) + return resp, err +} + // LookupVindexCreate is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) LookupVindexCreate(ctx context.Context, req *vtctldatapb.LookupVindexCreateRequest) (resp *vtctldatapb.LookupVindexCreateResponse, err error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.LookupVindexCreate") @@ -3012,6 +3055,21 @@ func (s *VtctldServer) LookupVindexExternalize(ctx context.Context, req *vtctlda return resp, err } +// LookupVindexInternalize is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) LookupVindexInternalize(ctx context.Context, req *vtctldatapb.LookupVindexInternalizeRequest) (resp *vtctldatapb.LookupVindexInternalizeResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.LookupVindexInternalize") + defer span.Finish() + + defer panicHandler(&err) + + span.Annotate("name", req.Name) + span.Annotate("keyspace", req.Keyspace) + span.Annotate("table_keyspace", req.TableKeyspace) + + resp, err = s.ws.LookupVindexInternalize(ctx, req) + return resp, err +} + // MaterializeCreate is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) MaterializeCreate(ctx context.Context, req *vtctldatapb.MaterializeCreateRequest) (resp *vtctldatapb.MaterializeCreateResponse, err error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.MaterializeCreate") @@ -3588,12 +3646,12 @@ func (s *VtctldServer) ReparentTablet(ctx context.Context, req *vtctldatapb.Repa return nil, err } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return nil, err } - if err = s.tmc.SetReplicationSource(ctx, tablet.Tablet, shard.PrimaryAlias, 0, "", false, reparentutil.IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet.Tablet), 0); err != nil { + if err = s.tmc.SetReplicationSource(ctx, tablet.Tablet, shard.PrimaryAlias, 0, "", false, policy.IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet.Tablet), 0); err != nil { return nil, err } @@ -3777,7 +3835,7 @@ func (s *VtctldServer) SetKeyspaceDurabilityPolicy(ctx context.Context, req *vtc return nil, err } - policyValid := reparentutil.CheckDurabilityPolicyExists(req.DurabilityPolicy) + policyValid := policy.CheckDurabilityPolicyExists(req.DurabilityPolicy) if !policyValid { err = vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "durability policy <%v> is not a valid policy. Please register it as a policy first", req.DurabilityPolicy) return nil, err @@ -4298,12 +4356,12 @@ func (s *VtctldServer) StartReplication(ctx context.Context, req *vtctldatapb.St return nil, err } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return nil, err } - if err = s.tmc.StartReplication(ctx, tablet.Tablet, reparentutil.IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet.Tablet)); err != nil { + if err = s.tmc.StartReplication(ctx, tablet.Tablet, policy.IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet.Tablet)); err != nil { log.Errorf("StartReplication: failed to start replication on %v: %v", alias, err) return nil, err } @@ -4403,12 +4461,12 @@ func (s *VtctldServer) TabletExternallyReparented(ctx context.Context, req *vtct return nil, err } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return nil, err } - if err = s.tmc.ChangeType(ctx, tablet.Tablet, topodatapb.TabletType_PRIMARY, reparentutil.SemiSyncAckers(durability, tablet.Tablet) > 0); err != nil { + if err = s.tmc.ChangeType(ctx, tablet.Tablet, topodatapb.TabletType_PRIMARY, policy.SemiSyncAckers(durability, tablet.Tablet) > 0); err != nil { log.Warningf("ChangeType(%v, PRIMARY): %v", topoproto.TabletAliasString(req.Tablet), err) return nil, err } @@ -4681,8 +4739,94 @@ func (s *VtctldServer) ValidateKeyspace(ctx context.Context, req *vtctldatapb.Va return resp, err } +// ValidatePermissionsKeyspace validates that all the permissions are the +// same in a keyspace. +func (s *VtctldServer) ValidatePermissionsKeyspace(ctx context.Context, req *vtctldatapb.ValidatePermissionsKeyspaceRequest) (resp *vtctldatapb.ValidatePermissionsKeyspaceResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.ValidatePermissionsKeyspace") + defer span.Finish() + + defer panicHandler(&err) + + span.Annotate("keyspace", req.Keyspace) + span.Annotate("shards", req.Shards) + + var shards []string + if len(req.Shards) != 0 { + // If the user has specified a list of specific shards, we'll use that. + shards = req.Shards + } else { + // Validate all of the shards. + shards, err = s.ts.GetShardNames(ctx, req.Keyspace) + if err != nil { + return nil, err + } + } + + if len(shards) == 0 { + return nil, fmt.Errorf("no shards found in keyspace %s", req.Keyspace) + } + sort.Strings(shards) + + // Find the reference permissions using the first shard's primary. + si, err := s.ts.GetShard(ctx, req.Keyspace, shards[0]) + if err != nil { + return nil, err + } + if !si.HasPrimary() { + return nil, fmt.Errorf("no primary tablet in shard %s/%s", req.Keyspace, shards[0]) + } + referenceAlias := si.PrimaryAlias + log.Infof("Gathering permissions for reference primary %s", topoproto.TabletAliasString(referenceAlias)) + pres, err := s.GetPermissions(ctx, &vtctldatapb.GetPermissionsRequest{ + TabletAlias: si.PrimaryAlias, + }) + if err != nil { + return nil, err + } + referencePermissions := pres.Permissions + + // Then diff the first/reference tablet with all the others. + eg, egctx := errgroup.WithContext(ctx) + for _, shard := range shards { + eg.Go(func() error { + aliases, err := s.ts.FindAllTabletAliasesInShard(egctx, req.Keyspace, shard) + if err != nil { + return err + } + for _, alias := range aliases { + if topoproto.TabletAliasEqual(alias, si.PrimaryAlias) { + continue + } + log.Infof("Gathering permissions for %s", topoproto.TabletAliasString(alias)) + presp, err := s.GetPermissions(ctx, &vtctldatapb.GetPermissionsRequest{ + TabletAlias: alias, + }) + if err != nil { + return err + } + + log.Infof("Diffing permissions between %s and %s", topoproto.TabletAliasString(referenceAlias), + topoproto.TabletAliasString(alias)) + er := &concurrency.AllErrorRecorder{} + tmutils.DiffPermissions(topoproto.TabletAliasString(referenceAlias), referencePermissions, + topoproto.TabletAliasString(alias), presp.Permissions, er) + if er.HasErrors() { + return er.Error() + } + } + return nil + }) + } + if err := eg.Wait(); err != nil { + return nil, fmt.Errorf("permissions diffs: %v", err) + } + + return &vtctldatapb.ValidatePermissionsKeyspaceResponse{}, nil +} + // ValidateSchemaKeyspace is a part of the vtctlservicepb.VtctldServer interface. -// It will diff the schema from all the tablets in the keyspace. +// It will diff the schema between the tablets in all shards -- or a subset if +// any specific shards are specified -- within the keyspace. func (s *VtctldServer) ValidateSchemaKeyspace(ctx context.Context, req *vtctldatapb.ValidateSchemaKeyspaceRequest) (resp *vtctldatapb.ValidateSchemaKeyspaceResponse, err error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.ValidateSchemaKeyspace") defer span.Finish() @@ -4690,17 +4834,25 @@ func (s *VtctldServer) ValidateSchemaKeyspace(ctx context.Context, req *vtctldat defer panicHandler(&err) span.Annotate("keyspace", req.Keyspace) + span.Annotate("shards", req.Shards) keyspace := req.Keyspace resp = &vtctldatapb.ValidateSchemaKeyspaceResponse{ Results: []string{}, } - shards, err := s.ts.GetShardNames(ctx, keyspace) - if err != nil { - resp.Results = append(resp.Results, fmt.Sprintf("TopologyServer.GetShardNames(%v) failed: %v", req.Keyspace, err)) - err = nil - return resp, err + var shards []string + if len(req.Shards) != 0 { + // If the user has specified a list of specific shards, we'll use that. + shards = req.Shards + } else { + // Otherwise we look at all the shards in the keyspace. + shards, err = s.ts.GetShardNames(ctx, keyspace) + if err != nil { + resp.Results = append(resp.Results, fmt.Sprintf("TopologyServer.GetShardNames(%s) failed: %v", req.Keyspace, err)) + err = nil + return resp, err + } } resp.ResultsByShard = make(map[string]*vtctldatapb.ValidateShardResponse, len(shards)) @@ -4743,7 +4895,7 @@ func (s *VtctldServer) ValidateSchemaKeyspace(ctx context.Context, req *vtctldat ) r := &tabletmanagerdatapb.GetSchemaRequest{ExcludeTables: req.ExcludeTables, IncludeViews: req.IncludeViews} - for _, shard := range shards[0:] { + for _, shard := range shards { wg.Add(1) go func(shard string) { defer wg.Done() diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 93f302a1097..252efc7d894 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -28,8 +28,11 @@ import ( "testing" "time" + "google.golang.org/protobuf/proto" + _flag "vitess.io/vitess/go/internal/flag" "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -607,15 +610,18 @@ func TestApplyVSchema(t *testing.T) { }, }) - origVSchema := &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "v1": { - Type: "hash", + origVSchema := &topo.KeyspaceVSchemaInfo{ + Name: tt.req.Keyspace, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "v1": { + Type: "hash", + }, }, }, } - err := ts.SaveVSchema(ctx, tt.req.Keyspace, origVSchema) + err := ts.SaveVSchema(ctx, origVSchema) require.NoError(t, err) origSrvVSchema := &vschemapb.SrvVSchema{ @@ -2576,12 +2582,12 @@ func TestCreateKeyspace(t *testing.T) { tests := []struct { name string topo map[string]*topodatapb.Keyspace - vschemas map[string]*vschemapb.Keyspace + vschemas map[string]*topo.KeyspaceVSchemaInfo req *vtctldatapb.CreateKeyspaceRequest expected *vtctldatapb.CreateKeyspaceResponse shouldErr bool vschemaShouldExist bool - expectedVSchema *vschemapb.Keyspace + expectedVSchema *topo.KeyspaceVSchemaInfo }{ { name: "normal keyspace", @@ -2599,8 +2605,11 @@ func TestCreateKeyspace(t *testing.T) { }, }, vschemaShouldExist: true, - expectedVSchema: &vschemapb.Keyspace{ - Sharded: false, + expectedVSchema: &topo.KeyspaceVSchemaInfo{ + Name: "testkeyspace", + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + }, }, shouldErr: false, }, @@ -2611,12 +2620,15 @@ func TestCreateKeyspace(t *testing.T) { KeyspaceType: topodatapb.KeyspaceType_NORMAL, }, }, - vschemas: map[string]*vschemapb.Keyspace{ + vschemas: map[string]*topo.KeyspaceVSchemaInfo{ "testkeyspace": { - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "h1": { - Type: "hash", + Name: "testkeyspace", + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "h1": { + Type: "hash", + }, }, }, }, @@ -2642,14 +2654,17 @@ func TestCreateKeyspace(t *testing.T) { }, }, vschemaShouldExist: true, - expectedVSchema: &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "h1": { - Type: "hash", + expectedVSchema: &topo.KeyspaceVSchemaInfo{ + Name: "testkeyspace", + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "h1": { + Type: "hash", + }, }, + RequireExplicitRouting: true, }, - RequireExplicitRouting: true, }, shouldErr: false, }, @@ -2695,9 +2710,12 @@ func TestCreateKeyspace(t *testing.T) { }, }, vschemaShouldExist: true, - expectedVSchema: &vschemapb.Keyspace{ - Sharded: false, - RequireExplicitRouting: true, + expectedVSchema: &topo.KeyspaceVSchemaInfo{ + Name: "testsnapshot", + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + RequireExplicitRouting: true, + }, }, shouldErr: false, }, @@ -2747,8 +2765,11 @@ func TestCreateKeyspace(t *testing.T) { }, }, vschemaShouldExist: true, - expectedVSchema: &vschemapb.Keyspace{ - Sharded: false, + expectedVSchema: &topo.KeyspaceVSchemaInfo{ + Name: "testkeyspace", + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + }, }, shouldErr: false, }, @@ -2771,26 +2792,30 @@ func TestCreateKeyspace(t *testing.T) { vschemaShouldExist: false, expectedVSchema: nil, shouldErr: false, - }, { + }, + { name: "keyspace with durability policy specified", topo: nil, req: &vtctldatapb.CreateKeyspaceRequest{ Name: "testkeyspace", Type: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, }, expected: &vtctldatapb.CreateKeyspaceResponse{ Keyspace: &vtctldatapb.Keyspace{ Name: "testkeyspace", Keyspace: &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, }, }, }, vschemaShouldExist: true, - expectedVSchema: &vschemapb.Keyspace{ - Sharded: false, + expectedVSchema: &topo.KeyspaceVSchemaInfo{ + Name: "testkeyspace", + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + }, }, shouldErr: false, }, @@ -2819,7 +2844,7 @@ func TestCreateKeyspace(t *testing.T) { } for name, vs := range tt.vschemas { - require.NoError(t, ts.SaveVSchema(ctx, name, vs), "error in SaveVSchema(%v, %+v)", name, vs) + require.NoError(t, ts.SaveVSchema(ctx, vs), "error in SaveVSchema(%v, %+v)", name, vs) } // Create the keyspace and make some assertions @@ -2828,7 +2853,6 @@ func TestCreateKeyspace(t *testing.T) { assert.Error(t, err) return } - assert.NoError(t, err) testutil.AssertKeyspacesEqual(t, tt.expected.Keyspace, resp.Keyspace, "%+v\n%+v\n", tt.expected.Keyspace, resp.Keyspace) @@ -2857,7 +2881,7 @@ func TestCreateKeyspace(t *testing.T) { return } assert.NoError(t, err) - utils.MustMatch(t, tt.expectedVSchema, vs) + require.True(t, proto.Equal(tt.expectedVSchema, vs), "expected vschema for %s: %+v, got: %+v", tt.req.Name, tt.expectedVSchema, vs) }) } } @@ -8381,11 +8405,14 @@ func TestGetVSchema(t *testing.T) { }) t.Run("found", func(t *testing.T) { - err := ts.SaveVSchema(ctx, "testkeyspace", &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "v1": { - Type: "hash", + err := ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "testkeyspace", + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "v1": { + Type: "hash", + }, }, }, }) @@ -11338,11 +11365,11 @@ func TestSetKeyspaceDurabilityPolicy(t *testing.T) { }, req: &vtctldatapb.SetKeyspaceDurabilityPolicyRequest{ Keyspace: "ks1", - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, }, expected: &vtctldatapb.SetKeyspaceDurabilityPolicyResponse{ Keyspace: &topodatapb.Keyspace{ - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, }, }, }, @@ -13881,11 +13908,11 @@ func TestValidateSchemaKeyspace(t *testing.T) { } tests := []*struct { - name string - req *vtctldatapb.ValidateSchemaKeyspaceRequest - expected *vtctldatapb.ValidateSchemaKeyspaceResponse - setup func() - shouldErr bool + name string + req *vtctldatapb.ValidateSchemaKeyspaceRequest + expected *vtctldatapb.ValidateSchemaKeyspaceResponse + setup func() + err string }{ { name: "valid schemas", @@ -13908,7 +13935,6 @@ func TestValidateSchemaKeyspace(t *testing.T) { Uid: 101, }, schema1) }, - shouldErr: false, }, { name: "different schemas", @@ -13931,7 +13957,6 @@ func TestValidateSchemaKeyspace(t *testing.T) { Uid: 101, }, schema2) }, - shouldErr: false, }, { name: "skip-no-primary: no primary", @@ -13956,7 +13981,6 @@ func TestValidateSchemaKeyspace(t *testing.T) { Uid: 201, }, schema1) }, - shouldErr: false, }, } @@ -13964,8 +13988,8 @@ func TestValidateSchemaKeyspace(t *testing.T) { t.Run(tt.name, func(t *testing.T) { tt.setup() resp, err := vtctld.ValidateSchemaKeyspace(ctx, tt.req) - if tt.shouldErr { - assert.Error(t, err) + if tt.err != "" { + assert.EqualError(t, err, tt.err) return } diff --git a/go/vt/vtctl/localvtctldclient/client_gen.go b/go/vt/vtctl/localvtctldclient/client_gen.go index 6867f4768f6..53b8f2d1b8c 100644 --- a/go/vt/vtctl/localvtctldclient/client_gen.go +++ b/go/vt/vtctl/localvtctldclient/client_gen.go @@ -201,6 +201,11 @@ func (client *localVtctldClient) ConcludeTransaction(ctx context.Context, in *vt return client.s.ConcludeTransaction(ctx, in) } +// CopySchemaShard is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) CopySchemaShard(ctx context.Context, in *vtctldatapb.CopySchemaShardRequest, opts ...grpc.CallOption) (*vtctldatapb.CopySchemaShardResponse, error) { + return client.s.CopySchemaShard(ctx, in) +} + // CreateKeyspace is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) CreateKeyspace(ctx context.Context, in *vtctldatapb.CreateKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.CreateKeyspaceResponse, error) { return client.s.CreateKeyspace(ctx, in) @@ -431,6 +436,11 @@ func (client *localVtctldClient) LaunchSchemaMigration(ctx context.Context, in * return client.s.LaunchSchemaMigration(ctx, in) } +// LookupVindexComplete is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) LookupVindexComplete(ctx context.Context, in *vtctldatapb.LookupVindexCompleteRequest, opts ...grpc.CallOption) (*vtctldatapb.LookupVindexCompleteResponse, error) { + return client.s.LookupVindexComplete(ctx, in) +} + // LookupVindexCreate is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) LookupVindexCreate(ctx context.Context, in *vtctldatapb.LookupVindexCreateRequest, opts ...grpc.CallOption) (*vtctldatapb.LookupVindexCreateResponse, error) { return client.s.LookupVindexCreate(ctx, in) @@ -441,6 +451,11 @@ func (client *localVtctldClient) LookupVindexExternalize(ctx context.Context, in return client.s.LookupVindexExternalize(ctx, in) } +// LookupVindexInternalize is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) LookupVindexInternalize(ctx context.Context, in *vtctldatapb.LookupVindexInternalizeRequest, opts ...grpc.CallOption) (*vtctldatapb.LookupVindexInternalizeResponse, error) { + return client.s.LookupVindexInternalize(ctx, in) +} + // MaterializeCreate is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) MaterializeCreate(ctx context.Context, in *vtctldatapb.MaterializeCreateRequest, opts ...grpc.CallOption) (*vtctldatapb.MaterializeCreateResponse, error) { return client.s.MaterializeCreate(ctx, in) @@ -732,6 +747,11 @@ func (client *localVtctldClient) ValidateKeyspace(ctx context.Context, in *vtctl return client.s.ValidateKeyspace(ctx, in) } +// ValidatePermissionsKeyspace is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) ValidatePermissionsKeyspace(ctx context.Context, in *vtctldatapb.ValidatePermissionsKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.ValidatePermissionsKeyspaceResponse, error) { + return client.s.ValidatePermissionsKeyspace(ctx, in) +} + // ValidateSchemaKeyspace is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) ValidateSchemaKeyspace(ctx context.Context, in *vtctldatapb.ValidateSchemaKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.ValidateSchemaKeyspaceResponse, error) { return client.s.ValidateSchemaKeyspace(ctx, in) diff --git a/go/vt/vtctl/reparentutil/durability_funcs.go b/go/vt/vtctl/reparentutil/durability_funcs.go index 63e123a685d..da53c1a3e15 100644 --- a/go/vt/vtctl/reparentutil/durability_funcs.go +++ b/go/vt/vtctl/reparentutil/durability_funcs.go @@ -19,16 +19,17 @@ package reparentutil import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtctl/reparentutil/promotionrule" ) // SemiSyncAckersForPrimary returns the list of tablets which are capable of sending Semi-Sync Acks for the given primary tablet -func SemiSyncAckersForPrimary(durability Durabler, primary *topodatapb.Tablet, allTablets []*topodatapb.Tablet) (semiSyncAckers []*topodatapb.Tablet) { +func SemiSyncAckersForPrimary(durability policy.Durabler, primary *topodatapb.Tablet, allTablets []*topodatapb.Tablet) (semiSyncAckers []*topodatapb.Tablet) { for _, tablet := range allTablets { if topoproto.TabletAliasEqual(primary.Alias, tablet.Alias) { continue } - if IsReplicaSemiSync(durability, primary, tablet) { + if policy.IsReplicaSemiSync(durability, primary, tablet) { semiSyncAckers = append(semiSyncAckers, tablet) } } @@ -37,7 +38,7 @@ func SemiSyncAckersForPrimary(durability Durabler, primary *topodatapb.Tablet, a // haveRevokedForTablet checks whether we have reached enough tablets such that the given primary eligible tablet cannot accept any new writes // The tablets reached should have their replication stopped and must be set to read only. -func haveRevokedForTablet(durability Durabler, primaryEligible *topodatapb.Tablet, tabletsReached []*topodatapb.Tablet, allTablets []*topodatapb.Tablet) bool { +func haveRevokedForTablet(durability policy.Durabler, primaryEligible *topodatapb.Tablet, tabletsReached []*topodatapb.Tablet, allTablets []*topodatapb.Tablet) bool { // if we have reached the primaryEligible tablet and stopped its replication and marked it read only, then it will not // accept any new writes if topoproto.IsTabletInList(primaryEligible, tabletsReached) { @@ -51,7 +52,7 @@ func haveRevokedForTablet(durability Durabler, primaryEligible *topodatapb.Table allSemiSyncAckers := SemiSyncAckersForPrimary(durability, primaryEligible, allTablets) // numOfSemiSyncAcksRequired is the number of semi sync Acks that the primaryEligible tablet requires - numOfSemiSyncAcksRequired := SemiSyncAckers(durability, primaryEligible) + numOfSemiSyncAcksRequired := policy.SemiSyncAckers(durability, primaryEligible) // if we have reached enough semi-sync Acking tablets such that the primaryEligible cannot accept a write // we have revoked from the tablet @@ -61,9 +62,9 @@ func haveRevokedForTablet(durability Durabler, primaryEligible *topodatapb.Table // haveRevoked checks whether we have reached enough tablets to guarantee that no tablet eligible to become a primary can accept any write // All the tablets reached must have their replication stopped and set to read only for us to guarantee that we have revoked access // from all the primary eligible tablets (prevent them from accepting any new writes) -func haveRevoked(durability Durabler, tabletsReached []*topodatapb.Tablet, allTablets []*topodatapb.Tablet) bool { +func haveRevoked(durability policy.Durabler, tabletsReached []*topodatapb.Tablet, allTablets []*topodatapb.Tablet) bool { for _, tablet := range allTablets { - if PromotionRule(durability, tablet) == promotionrule.MustNot { + if policy.PromotionRule(durability, tablet) == promotionrule.MustNot { continue } if !haveRevokedForTablet(durability, tablet, tabletsReached, allTablets) { @@ -74,7 +75,7 @@ func haveRevoked(durability Durabler, tabletsReached []*topodatapb.Tablet, allTa } // canEstablishForTablet checks whether we have reached enough tablets to say that the given primary eligible tablet will be able to accept new writes -func canEstablishForTablet(durability Durabler, primaryEligible *topodatapb.Tablet, tabletsReached []*topodatapb.Tablet) bool { +func canEstablishForTablet(durability policy.Durabler, primaryEligible *topodatapb.Tablet, tabletsReached []*topodatapb.Tablet) bool { // if we have not reached the primaryEligible tablet, then it cannot be considered eligible to accept writes // since it might have been stopped if !topoproto.IsTabletInList(primaryEligible, tabletsReached) { @@ -85,7 +86,7 @@ func canEstablishForTablet(durability Durabler, primaryEligible *topodatapb.Tabl semiSyncAckersReached := SemiSyncAckersForPrimary(durability, primaryEligible, tabletsReached) // numOfSemiSyncAcksRequired is the number of semi sync Acks that the primaryEligible tablet requires - numOfSemiSyncAcksRequired := SemiSyncAckers(durability, primaryEligible) + numOfSemiSyncAcksRequired := policy.SemiSyncAckers(durability, primaryEligible) // if we have reached enough semi-sync Acking tablets such that the primaryEligible can accept a write // we can safely promote this tablet diff --git a/go/vt/vtctl/reparentutil/durability_funcs_test.go b/go/vt/vtctl/reparentutil/durability_funcs_test.go index 21eb308a4b0..737d3e40346 100644 --- a/go/vt/vtctl/reparentutil/durability_funcs_test.go +++ b/go/vt/vtctl/reparentutil/durability_funcs_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) var ( @@ -73,25 +74,25 @@ func TestSemiSyncAckersForPrimary(t *testing.T) { }{ { name: "no other tablets", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, primary: primaryTablet, allTablets: []*topodatapb.Tablet{primaryTablet}, wantSemiSyncAckers: nil, }, { name: "'none' durability policy", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, primary: primaryTablet, allTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, replicaCrossCellTablet, rdonlyCrossCellTablet}, wantSemiSyncAckers: nil, }, { name: "'semi_sync' durability policy", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, primary: primaryTablet, allTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, replicaCrossCellTablet, rdonlyCrossCellTablet}, wantSemiSyncAckers: []*topodatapb.Tablet{replicaTablet, replicaCrossCellTablet}, }, { name: "'cross_cell' durability policy", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, primary: primaryTablet, allTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, replicaCrossCellTablet, rdonlyCrossCellTablet}, wantSemiSyncAckers: []*topodatapb.Tablet{replicaCrossCellTablet}, @@ -99,7 +100,7 @@ func TestSemiSyncAckersForPrimary(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - durability, err := GetDurabilityPolicy(tt.durabilityPolicy) + durability, err := policy.GetDurabilityPolicy(tt.durabilityPolicy) require.NoError(t, err, "error setting durability policy") semiSyncAckers := SemiSyncAckersForPrimary(durability, tt.primary, tt.allTablets) require.Equal(t, tt.wantSemiSyncAckers, semiSyncAckers) @@ -118,7 +119,7 @@ func Test_haveRevokedForTablet(t *testing.T) { }{ { name: "'none' durability policy - not revoked", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, primaryEligible: primaryTablet, allTablets: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -129,7 +130,7 @@ func Test_haveRevokedForTablet(t *testing.T) { revoked: false, }, { name: "'none' durability policy - revoked", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, primaryEligible: primaryTablet, allTablets: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -140,7 +141,7 @@ func Test_haveRevokedForTablet(t *testing.T) { revoked: true, }, { name: "'semi_sync' durability policy - revoked", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, primaryEligible: primaryTablet, allTablets: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -151,7 +152,7 @@ func Test_haveRevokedForTablet(t *testing.T) { revoked: true, }, { name: "'semi_sync' durability policy - not revoked", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, primaryEligible: primaryTablet, allTablets: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -162,7 +163,7 @@ func Test_haveRevokedForTablet(t *testing.T) { revoked: false, }, { name: "'cross_cell' durability policy - revoked", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, primaryEligible: primaryTablet, allTablets: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -173,7 +174,7 @@ func Test_haveRevokedForTablet(t *testing.T) { revoked: true, }, { name: "'cross_cell' durability policy - not revoked", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, primaryEligible: primaryTablet, allTablets: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -184,7 +185,7 @@ func Test_haveRevokedForTablet(t *testing.T) { revoked: false, }, { name: "'cross_cell' durability policy - primary in list", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, primaryEligible: primaryTablet, allTablets: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -197,7 +198,7 @@ func Test_haveRevokedForTablet(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - durability, err := GetDurabilityPolicy(tt.durabilityPolicy) + durability, err := policy.GetDurabilityPolicy(tt.durabilityPolicy) require.NoError(t, err) out := haveRevokedForTablet(durability, tt.primaryEligible, tt.tabletsReached, tt.allTablets) require.Equal(t, tt.revoked, out) @@ -215,7 +216,7 @@ func Test_haveRevoked(t *testing.T) { }{ { name: "'none' durability policy - all tablets revoked", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, }, @@ -225,7 +226,7 @@ func Test_haveRevoked(t *testing.T) { revoked: true, }, { name: "'semi_sync' durability policy - all tablets revoked", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, }, @@ -235,7 +236,7 @@ func Test_haveRevoked(t *testing.T) { revoked: true, }, { name: "'cross_cell' durability policy - all tablets revoked", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, }, @@ -245,7 +246,7 @@ func Test_haveRevoked(t *testing.T) { revoked: true, }, { name: "'none' durability policy - revoked", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaTablet, replicaCrossCellTablet, }, @@ -255,7 +256,7 @@ func Test_haveRevoked(t *testing.T) { revoked: true, }, { name: "'semi_sync' durability policy - revoked", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, tabletsReached: []*topodatapb.Tablet{ replicaTablet, replicaCrossCellTablet, rdonlyTablet, }, @@ -265,7 +266,7 @@ func Test_haveRevoked(t *testing.T) { revoked: true, }, { name: "'cross_cell' durability policy - revoked", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, tabletsReached: []*topodatapb.Tablet{ replicaCrossCellTablet, }, @@ -275,7 +276,7 @@ func Test_haveRevoked(t *testing.T) { revoked: true, }, { name: "'none' durability policy - not revoked", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, }, @@ -285,7 +286,7 @@ func Test_haveRevoked(t *testing.T) { revoked: false, }, { name: "'semi_sync' durability policy - not revoked", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, tabletsReached: []*topodatapb.Tablet{ primaryTablet, rdonlyCrossCellTablet, rdonlyTablet, }, @@ -295,7 +296,7 @@ func Test_haveRevoked(t *testing.T) { revoked: false, }, { name: "'cross_cell' durability policy - not revoked", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, tabletsReached: []*topodatapb.Tablet{ primaryTablet, rdonlyCrossCellTablet, rdonlyTablet, }, @@ -307,7 +308,7 @@ func Test_haveRevoked(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - durability, err := GetDurabilityPolicy(tt.durabilityPolicy) + durability, err := policy.GetDurabilityPolicy(tt.durabilityPolicy) require.NoError(t, err) out := haveRevoked(durability, tt.tabletsReached, tt.allTablets) require.Equal(t, tt.revoked, out) @@ -325,7 +326,7 @@ func Test_canEstablishForTablet(t *testing.T) { }{ { name: "primary not reached", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, primaryEligible: primaryTablet, tabletsReached: []*topodatapb.Tablet{ replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -333,7 +334,7 @@ func Test_canEstablishForTablet(t *testing.T) { canEstablish: false, }, { name: "not established", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, primaryEligible: primaryTablet, tabletsReached: []*topodatapb.Tablet{ primaryTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -341,7 +342,7 @@ func Test_canEstablishForTablet(t *testing.T) { canEstablish: false, }, { name: "not established", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, primaryEligible: primaryTablet, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaTablet, rdonlyCrossCellTablet, rdonlyTablet, @@ -349,7 +350,7 @@ func Test_canEstablishForTablet(t *testing.T) { canEstablish: false, }, { name: "established", - durabilityPolicy: "none", + durabilityPolicy: policy.DurabilityNone, primaryEligible: primaryTablet, tabletsReached: []*topodatapb.Tablet{ primaryTablet, @@ -357,7 +358,7 @@ func Test_canEstablishForTablet(t *testing.T) { canEstablish: true, }, { name: "established", - durabilityPolicy: "semi_sync", + durabilityPolicy: policy.DurabilitySemiSync, primaryEligible: primaryTablet, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaTablet, @@ -365,7 +366,7 @@ func Test_canEstablishForTablet(t *testing.T) { canEstablish: true, }, { name: "established", - durabilityPolicy: "cross_cell", + durabilityPolicy: policy.DurabilityCrossCell, primaryEligible: primaryTablet, tabletsReached: []*topodatapb.Tablet{ primaryTablet, replicaCrossCellTablet, @@ -375,7 +376,7 @@ func Test_canEstablishForTablet(t *testing.T) { } for _, tt := range tests { t.Run(fmt.Sprintf("'%s' durability policy - %s", tt.durabilityPolicy, tt.name), func(t *testing.T) { - durability, err := GetDurabilityPolicy(tt.durabilityPolicy) + durability, err := policy.GetDurabilityPolicy(tt.durabilityPolicy) require.NoError(t, err) require.Equalf(t, tt.canEstablish, canEstablishForTablet(durability, tt.primaryEligible, tt.tabletsReached), "canEstablishForTablet(%v, %v)", tt.primaryEligible, tt.tabletsReached) }) diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter.go b/go/vt/vtctl/reparentutil/emergency_reparenter.go index 70faf8958c7..5f7d3140c7b 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter.go @@ -24,6 +24,7 @@ import ( "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/event" "vitess.io/vitess/go/sets" @@ -66,7 +67,7 @@ type EmergencyReparentOptions struct { // Private options managed internally. We use value passing to avoid leaking // these details back out. lockAction string - durability Durabler + durability policy.Durabler } // counters for Emergency Reparent Shard @@ -181,7 +182,7 @@ func (erp *EmergencyReparenter) reparentShardLocked(ctx context.Context, ev *eve } erp.logger.Infof("Getting a new durability policy for %v", keyspaceDurability) - opts.durability, err = GetDurabilityPolicy(keyspaceDurability) + opts.durability, err = policy.GetDurabilityPolicy(keyspaceDurability) if err != nil { return err } @@ -539,11 +540,11 @@ func (erp *EmergencyReparenter) reparentReplicas( if ev.ShardInfo.PrimaryAlias == nil { erp.logger.Infof("setting up %v as new primary for an uninitialized cluster", alias) // we call InitPrimary when the PrimaryAlias in the ShardInfo is empty. This happens when we have an uninitialized cluster. - position, err = erp.tmc.InitPrimary(primaryCtx, tablet, SemiSyncAckers(opts.durability, tablet) > 0) + position, err = erp.tmc.InitPrimary(primaryCtx, tablet, policy.SemiSyncAckers(opts.durability, tablet) > 0) } else { erp.logger.Infof("starting promotion for the new primary - %v", alias) // we call PromoteReplica which changes the tablet type, fixes the semi-sync, set the primary to read-write and flushes the binlogs - position, err = erp.tmc.PromoteReplica(primaryCtx, tablet, SemiSyncAckers(opts.durability, tablet) > 0) + position, err = erp.tmc.PromoteReplica(primaryCtx, tablet, policy.SemiSyncAckers(opts.durability, tablet) > 0) } if err != nil { return vterrors.Wrapf(err, "primary-elect tablet %v failed to be upgraded to primary: %v", alias, err) @@ -574,7 +575,7 @@ func (erp *EmergencyReparenter) reparentReplicas( forceStart = fs } - err := erp.tmc.SetReplicationSource(replCtx, ti.Tablet, newPrimaryTablet.Alias, 0, "", forceStart, IsReplicaSemiSync(opts.durability, newPrimaryTablet, ti.Tablet), 0) + err := erp.tmc.SetReplicationSource(replCtx, ti.Tablet, newPrimaryTablet.Alias, 0, "", forceStart, policy.IsReplicaSemiSync(opts.durability, newPrimaryTablet, ti.Tablet), 0) if err != nil { err = vterrors.Wrapf(err, "tablet %v SetReplicationSource failed: %v", alias, err) rec.RecordError(err) @@ -746,7 +747,7 @@ func (erp *EmergencyReparenter) filterValidCandidates(validTablets []*topodatapb for _, tablet := range validTablets { tabletAliasStr := topoproto.TabletAliasString(tablet.Alias) // Remove tablets which have MustNot promote rule since they must never be promoted - if PromotionRule(opts.durability, tablet) == promotionrule.MustNot { + if policy.PromotionRule(opts.durability, tablet) == promotionrule.MustNot { erp.logger.Infof("Removing %s from list of valid candidates for promotion because it has the Must Not promote rule", tabletAliasStr) if opts.NewPrimaryAlias != nil && topoproto.TabletAliasEqual(opts.NewPrimaryAlias, tablet.Alias) { return nil, vterrors.Errorf(vtrpc.Code_ABORTED, "proposed primary %s has a must not promotion rule", topoproto.TabletAliasString(opts.NewPrimaryAlias)) diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter_test.go b/go/vt/vtctl/reparentutil/emergency_reparenter_test.go index 3669c34dc11..840df41d6e2 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter_test.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter_test.go @@ -28,6 +28,7 @@ import ( "vitess.io/vitess/go/mysql/replication" logutilpb "vitess.io/vitess/go/vt/proto/logutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vttablet/tmclient" "vitess.io/vitess/go/mysql" @@ -129,7 +130,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }{ { name: "success", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{ PopulateReparentJournalResults: map[string]error{ @@ -238,7 +239,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "success - 1 replica and 1 rdonly failure", - durability: "semi_sync", + durability: policy.DurabilitySemiSync, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{ PopulateReparentJournalResults: map[string]error{ @@ -372,7 +373,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { // Here, all our tablets are tied, so we're going to explicitly pick // zone1-101. name: "success with requested primary-elect", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{NewPrimaryAlias: &topodatapb.TabletAlias{ Cell: "zone1", Uid: 101, @@ -483,7 +484,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "success with existing primary", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{ DemotePrimaryResults: map[string]struct { @@ -594,7 +595,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "shard not found", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{}, unlockTopo: true, // we shouldn't try to lock the nonexistent shard @@ -607,7 +608,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "cannot stop replication", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{ StopReplicationAndGetStatusResults: map[string]struct { @@ -666,7 +667,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "lost topo lock", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{ StopReplicationAndGetStatusResults: map[string]struct { @@ -725,7 +726,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "cannot get reparent candidates", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{ StopReplicationAndGetStatusResults: map[string]struct { @@ -799,7 +800,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "zero valid reparent candidates", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{}, shards: []*vtctldatapb.Shard{ @@ -816,7 +817,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "error waiting for relay logs to apply", - durability: "none", + durability: policy.DurabilityNone, // one replica is going to take a minute to apply relay logs emergencyReparentOps: EmergencyReparentOptions{ WaitReplicasTimeout: time.Millisecond * 50, @@ -911,7 +912,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "requested primary-elect is not in tablet map", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{NewPrimaryAlias: &topodatapb.TabletAlias{ Cell: "zone1", Uid: 200, @@ -1001,7 +1002,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "requested primary-elect is not winning primary-elect", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{NewPrimaryAlias: &topodatapb.TabletAlias{ // we're requesting a tablet that's behind in replication Cell: "zone1", Uid: 102, @@ -1124,7 +1125,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "cannot promote new primary", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{NewPrimaryAlias: &topodatapb.TabletAlias{ Cell: "zone1", Uid: 102, @@ -1237,7 +1238,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "promotion-rule - no valid candidates for emergency reparent", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{}, tmc: &testutil.TabletManagerClient{ PopulateReparentJournalResults: map[string]error{ @@ -1344,7 +1345,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "proposed primary - must not promotion rule", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{ NewPrimaryAlias: &topodatapb.TabletAlias{ Cell: "zone1", @@ -1456,7 +1457,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "cross cell - no valid candidates", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{PreventCrossCellPromotion: true}, tmc: &testutil.TabletManagerClient{ PopulateReparentJournalResults: map[string]error{ @@ -1575,7 +1576,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "proposed primary in a different cell", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{ PreventCrossCellPromotion: true, NewPrimaryAlias: &topodatapb.TabletAlias{ @@ -1700,7 +1701,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "proposed primary cannot make progress", - durability: "cross_cell", + durability: policy.DurabilityCrossCell, emergencyReparentOps: EmergencyReparentOptions{ NewPrimaryAlias: &topodatapb.TabletAlias{ Cell: "zone1", @@ -1815,7 +1816,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { }, { name: "expected primary mismatch", - durability: "none", + durability: policy.DurabilityNone, emergencyReparentOps: EmergencyReparentOptions{ ExpectedPrimaryAlias: &topodatapb.TabletAlias{ Cell: "zone1", @@ -2333,7 +2334,7 @@ func TestEmergencyReparenter_promotionOfNewPrimary(t *testing.T) { }, } - durability, _ := GetDurabilityPolicy("none") + durability, _ := policy.GetDurabilityPolicy(policy.DurabilityNone) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -3021,7 +3022,7 @@ func TestEmergencyReparenter_findMostAdvanced(t *testing.T) { }, } - durability, _ := GetDurabilityPolicy("none") + durability, _ := policy.GetDurabilityPolicy(policy.DurabilityNone) for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -3502,7 +3503,7 @@ func TestEmergencyReparenter_reparentReplicas(t *testing.T) { }, } - durability, _ := GetDurabilityPolicy("none") + durability, _ := policy.GetDurabilityPolicy(policy.DurabilityNone) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.remoteOpTimeout != 0 { @@ -4092,7 +4093,7 @@ func TestEmergencyReparenter_promoteIntermediateSource(t *testing.T) { }, } - durability, _ := GetDurabilityPolicy("none") + durability, _ := policy.GetDurabilityPolicy(policy.DurabilityNone) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() @@ -4336,7 +4337,7 @@ func TestEmergencyReparenter_identifyPrimaryCandidate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - durability, _ := GetDurabilityPolicy("none") + durability, _ := policy.GetDurabilityPolicy(policy.DurabilityNone) test.emergencyReparentOps.durability = durability logger := logutil.NewMemoryLogger() @@ -4355,7 +4356,7 @@ func TestEmergencyReparenter_identifyPrimaryCandidate(t *testing.T) { // TestParentContextCancelled tests that even if the parent context of reparentReplicas cancels, we should not cancel the context of // SetReplicationSource since there could be tablets that are running it even after ERS completes. func TestParentContextCancelled(t *testing.T) { - durability, err := GetDurabilityPolicy("none") + durability, err := policy.GetDurabilityPolicy(policy.DurabilityNone) require.NoError(t, err) // Setup ERS options with a very high wait replicas timeout emergencyReparentOps := EmergencyReparentOptions{IgnoreReplicas: sets.New[string]("zone1-0000000404"), WaitReplicasTimeout: time.Minute, durability: durability} @@ -4486,28 +4487,28 @@ func TestEmergencyReparenter_filterValidCandidates(t *testing.T) { }{ { name: "filter must not", - durability: "none", + durability: policy.DurabilityNone, validTablets: allTablets, tabletsReachable: allTablets, tabletsTakingBackup: noTabletsTakingBackup, filteredTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet, replicaCrossCellTablet}, }, { name: "host taking backup must not be on the list when there are other candidates", - durability: "none", + durability: policy.DurabilityNone, validTablets: allTablets, tabletsReachable: []*topodatapb.Tablet{replicaTablet, replicaCrossCellTablet, rdonlyTablet, rdonlyCrossCellTablet}, tabletsTakingBackup: replicaTakingBackup, filteredTablets: []*topodatapb.Tablet{replicaCrossCellTablet}, }, { name: "host taking backup must be the only one on the list when there are no other candidates", - durability: "none", + durability: policy.DurabilityNone, validTablets: allTablets, tabletsReachable: []*topodatapb.Tablet{replicaTablet, rdonlyTablet, rdonlyCrossCellTablet}, tabletsTakingBackup: replicaTakingBackup, filteredTablets: []*topodatapb.Tablet{replicaTablet}, }, { name: "filter cross cell", - durability: "none", + durability: policy.DurabilityNone, validTablets: allTablets, tabletsReachable: allTablets, tabletsTakingBackup: noTabletsTakingBackup, @@ -4523,14 +4524,14 @@ func TestEmergencyReparenter_filterValidCandidates(t *testing.T) { filteredTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet}, }, { name: "filter establish", - durability: "cross_cell", + durability: policy.DurabilityCrossCell, validTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet}, tabletsReachable: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, rdonlyCrossCellTablet}, tabletsTakingBackup: noTabletsTakingBackup, filteredTablets: nil, }, { name: "filter mixed", - durability: "cross_cell", + durability: policy.DurabilityCrossCell, prevPrimary: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ Cell: "zone-2", @@ -4545,7 +4546,7 @@ func TestEmergencyReparenter_filterValidCandidates(t *testing.T) { filteredTablets: []*topodatapb.Tablet{replicaCrossCellTablet}, }, { name: "error - requested primary must not", - durability: "none", + durability: policy.DurabilityNone, validTablets: allTablets, tabletsReachable: allTablets, tabletsTakingBackup: noTabletsTakingBackup, @@ -4555,7 +4556,7 @@ func TestEmergencyReparenter_filterValidCandidates(t *testing.T) { errShouldContain: "proposed primary zone-1-0000000003 has a must not promotion rule", }, { name: "error - requested primary not in same cell", - durability: "none", + durability: policy.DurabilityNone, validTablets: allTablets, tabletsReachable: allTablets, tabletsTakingBackup: noTabletsTakingBackup, @@ -4567,7 +4568,7 @@ func TestEmergencyReparenter_filterValidCandidates(t *testing.T) { errShouldContain: "proposed primary zone-2-0000000002 is is a different cell as the previous primary", }, { name: "error - requested primary cannot establish", - durability: "cross_cell", + durability: policy.DurabilityCrossCell, validTablets: allTablets, tabletsTakingBackup: noTabletsTakingBackup, tabletsReachable: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, rdonlyCrossCellTablet}, @@ -4579,7 +4580,7 @@ func TestEmergencyReparenter_filterValidCandidates(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - durability, err := GetDurabilityPolicy(tt.durability) + durability, err := policy.GetDurabilityPolicy(tt.durability) require.NoError(t, err) tt.opts.durability = durability logger := logutil.NewMemoryLogger() @@ -5525,7 +5526,7 @@ func TestEmergencyReparenterFindErrantGTIDs(t *testing.T) { slices.Sort(keys) require.ElementsMatch(t, tt.wantedCandidates, keys) - dp, err := GetDurabilityPolicy("semi_sync") + dp, err := policy.GetDurabilityPolicy(policy.DurabilitySemiSync) require.NoError(t, err) ers := EmergencyReparenter{logger: logutil.NewCallbackLogger(func(*logutilpb.Event) {})} winningPrimary, _, err := ers.findMostAdvanced(candidates, tt.tabletMap, EmergencyReparentOptions{durability: dp}) diff --git a/go/vt/vtctl/reparentutil/planned_reparenter.go b/go/vt/vtctl/reparentutil/planned_reparenter.go index 91669e33b5f..dcd6dc7c590 100644 --- a/go/vt/vtctl/reparentutil/planned_reparenter.go +++ b/go/vt/vtctl/reparentutil/planned_reparenter.go @@ -36,6 +36,7 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools/events" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tmclient" ) @@ -71,7 +72,7 @@ type PlannedReparentOptions struct { // back out to the caller. lockAction string - durability Durabler + durability policy.Durabler } // NewPlannedReparenter returns a new PlannedReparenter object, ready to perform @@ -256,7 +257,7 @@ func (pr *PlannedReparenter) performGracefulPromotion( setSourceCtx, setSourceCancel := context.WithTimeout(ctx, opts.WaitReplicasTimeout) defer setSourceCancel() - if err := pr.tmc.SetReplicationSource(setSourceCtx, primaryElect, currentPrimary.Alias, 0, snapshotPos, true, IsReplicaSemiSync(opts.durability, currentPrimary.Tablet, primaryElect), 0); err != nil { + if err := pr.tmc.SetReplicationSource(setSourceCtx, primaryElect, currentPrimary.Alias, 0, snapshotPos, true, policy.IsReplicaSemiSync(opts.durability, currentPrimary.Tablet, primaryElect), 0); err != nil { return vterrors.Wrapf(err, "replication on primary-elect %v did not catch up in time; replication must be healthy to perform PlannedReparent", primaryElectAliasStr) } @@ -304,7 +305,7 @@ func (pr *PlannedReparenter) performGracefulPromotion( undoCtx, undoCancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) defer undoCancel() - if undoErr := pr.tmc.UndoDemotePrimary(undoCtx, currentPrimary.Tablet, SemiSyncAckers(opts.durability, currentPrimary.Tablet) > 0); undoErr != nil { + if undoErr := pr.tmc.UndoDemotePrimary(undoCtx, currentPrimary.Tablet, policy.SemiSyncAckers(opts.durability, currentPrimary.Tablet) > 0); undoErr != nil { pr.logger.Warningf("encountered error while performing UndoDemotePrimary(%v): %v", currentPrimary.AliasString(), undoErr) finalWaitErr = vterrors.Wrapf(finalWaitErr, "encountered error while performing UndoDemotePrimary(%v): %v", currentPrimary.AliasString(), undoErr) } @@ -332,7 +333,7 @@ func (pr *PlannedReparenter) performInitialPromotion( // This is done to guarantee safety, in the sense that the semi-sync is on before we start accepting writes. // However, during initialization, it is likely that the database would not be created in the MySQL instance. // Therefore, we have to first set read-write mode, create the database and then fix semi-sync, otherwise we get blocked. - rp, err := pr.tmc.InitPrimary(promoteCtx, primaryElect, SemiSyncAckers(opts.durability, primaryElect) > 0) + rp, err := pr.tmc.InitPrimary(promoteCtx, primaryElect, policy.SemiSyncAckers(opts.durability, primaryElect) > 0) if err != nil { return "", vterrors.Wrapf(err, "primary-elect tablet %v failed to be promoted to primary; please try again", primaryElectAliasStr) } @@ -521,7 +522,7 @@ func (pr *PlannedReparenter) reparentShardLocked( } pr.logger.Infof("Getting a new durability policy for %v", keyspaceDurability) - opts.durability, err = GetDurabilityPolicy(keyspaceDurability) + opts.durability, err = policy.GetDurabilityPolicy(keyspaceDurability) if err != nil { return err } @@ -693,7 +694,7 @@ func (pr *PlannedReparenter) reparentTablets( // that it needs to start replication after transitioning from // PRIMARY => REPLICA. forceStartReplication := false - if err := pr.tmc.SetReplicationSource(replCtx, tablet, ev.NewPrimary.Alias, reparentJournalTimestamp, "", forceStartReplication, IsReplicaSemiSync(opts.durability, ev.NewPrimary, tablet), 0); err != nil { + if err := pr.tmc.SetReplicationSource(replCtx, tablet, ev.NewPrimary.Alias, reparentJournalTimestamp, "", forceStartReplication, policy.IsReplicaSemiSync(opts.durability, ev.NewPrimary, tablet), 0); err != nil { rec.RecordError(vterrors.Wrapf(err, "tablet %v failed to SetReplicationSource(%v): %v", alias, primaryElectAliasStr, err)) } }(alias, tabletInfo.Tablet) @@ -702,7 +703,7 @@ func (pr *PlannedReparenter) reparentTablets( // If `PromoteReplica` call is required, we should call it and use the position that it returns. if promoteReplicaRequired { // Promote the candidate primary to type:PRIMARY. - primaryPosition, err := pr.tmc.PromoteReplica(replCtx, ev.NewPrimary, SemiSyncAckers(opts.durability, ev.NewPrimary) > 0) + primaryPosition, err := pr.tmc.PromoteReplica(replCtx, ev.NewPrimary, policy.SemiSyncAckers(opts.durability, ev.NewPrimary) > 0) if err != nil { pr.logger.Warningf("primary %v failed to PromoteReplica; cancelling replica reparent attempts", primaryElectAliasStr) replCancel() diff --git a/go/vt/vtctl/reparentutil/planned_reparenter_flaky_test.go b/go/vt/vtctl/reparentutil/planned_reparenter_flaky_test.go index 8e2ee8f9df7..148d9fd812c 100644 --- a/go/vt/vtctl/reparentutil/planned_reparenter_flaky_test.go +++ b/go/vt/vtctl/reparentutil/planned_reparenter_flaky_test.go @@ -25,6 +25,7 @@ import ( "time" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/test/utils" @@ -557,6 +558,11 @@ func TestPlannedReparenter_getLockAction(t *testing.T) { } } +func getDurabilityPolicy(policyName string) policy.Durabler { + p, _ := policy.GetDurabilityPolicy(policyName) + return p +} + func TestPlannedReparenter_preflightChecks(t *testing.T) { t.Parallel() @@ -791,7 +797,6 @@ func TestPlannedReparenter_preflightChecks(t *testing.T) { Cell: "zone1", Uid: 500, }, - durability: &durabilityNone{}, }, expectedIsNoop: false, expectedEvent: &events.Reparent{ @@ -819,7 +824,7 @@ func TestPlannedReparenter_preflightChecks(t *testing.T) { Cell: "zone1", Uid: 100, }, - durability: &durabilityNone{}, + durability: getDurabilityPolicy(policy.DurabilityNone), }, shouldErr: false, }, @@ -889,7 +894,6 @@ func TestPlannedReparenter_preflightChecks(t *testing.T) { Cell: "zone1", Uid: 500, }, - durability: &durabilityNone{}, }, expectedIsNoop: false, expectedEvent: &events.Reparent{ @@ -917,7 +921,7 @@ func TestPlannedReparenter_preflightChecks(t *testing.T) { Cell: "zone1", Uid: 101, }, - durability: &durabilityNone{}, + durability: getDurabilityPolicy(policy.DurabilityNone), }, shouldErr: false, }, @@ -1148,7 +1152,7 @@ func TestPlannedReparenter_preflightChecks(t *testing.T) { Cell: "zone1", Uid: 500, }, - durability: &durabilityCrossCell{}, + durability: getDurabilityPolicy(policy.DurabilityCrossCell), }, expectedIsNoop: true, expectedEvent: &events.Reparent{ @@ -1186,7 +1190,7 @@ func TestPlannedReparenter_preflightChecks(t *testing.T) { pr := NewPlannedReparenter(ts, tt.tmc, logger) if tt.opts.durability == nil { - durability, err := GetDurabilityPolicy("none") + durability, err := policy.GetDurabilityPolicy(policy.DurabilityNone) require.NoError(t, err) tt.opts.durability = durability } @@ -1799,7 +1803,7 @@ func TestPlannedReparenter_performGracefulPromotion(t *testing.T) { ctx = _ctx } - durability, err := GetDurabilityPolicy("none") + durability, err := policy.GetDurabilityPolicy(policy.DurabilityNone) require.NoError(t, err) tt.opts.durability = durability @@ -1946,7 +1950,7 @@ func TestPlannedReparenter_performInitialPromotion(t *testing.T) { ctx = _ctx } - durability, err := GetDurabilityPolicy("none") + durability, err := policy.GetDurabilityPolicy(policy.DurabilityNone) require.NoError(t, err) pos, err := pr.performInitialPromotion( ctx, @@ -3423,7 +3427,7 @@ func TestPlannedReparenter_reparentTablets(t *testing.T) { }{ { name: "success - durability = none", - durability: "none", + durability: policy.DurabilityNone, tmc: &testutil.TabletManagerClient{ PopulateReparentJournalResults: map[string]error{ "zone1-0000000100": nil, @@ -3490,7 +3494,7 @@ func TestPlannedReparenter_reparentTablets(t *testing.T) { }, { name: "success - durability = semi_sync", - durability: "semi_sync", + durability: policy.DurabilitySemiSync, tmc: &testutil.TabletManagerClient{ PopulateReparentJournalResults: map[string]error{ "zone1-0000000100": nil, @@ -3556,7 +3560,7 @@ func TestPlannedReparenter_reparentTablets(t *testing.T) { shouldErr: false, }, { name: "success - promote replica required", - durability: "semi_sync", + durability: policy.DurabilitySemiSync, promoteReplicaRequired: true, tmc: &testutil.TabletManagerClient{ PromoteReplicaResults: map[string]struct { @@ -3632,7 +3636,7 @@ func TestPlannedReparenter_reparentTablets(t *testing.T) { shouldErr: false, }, { name: "Promote replica failed", - durability: "semi_sync", + durability: policy.DurabilitySemiSync, promoteReplicaRequired: true, tmc: &testutil.TabletManagerClient{ PromoteReplicaResults: map[string]struct { @@ -3977,11 +3981,11 @@ func TestPlannedReparenter_reparentTablets(t *testing.T) { t.Parallel() pr := NewPlannedReparenter(nil, tt.tmc, logger) - durabilityPolicy := "none" + durabilityPolicy := policy.DurabilityNone if tt.durability != "" { durabilityPolicy = tt.durability } - durability, err := GetDurabilityPolicy(durabilityPolicy) + durability, err := policy.GetDurabilityPolicy(durabilityPolicy) require.NoError(t, err) tt.opts.durability = durability err = pr.reparentTablets(ctx, tt.ev, tt.reparentJournalPosition, tt.promoteReplicaRequired, tt.tabletMap, tt.opts) diff --git a/go/vt/vtctl/reparentutil/durability.go b/go/vt/vtctl/reparentutil/policy/durability.go similarity index 84% rename from go/vt/vtctl/reparentutil/durability.go rename to go/vt/vtctl/reparentutil/policy/durability.go index 29a5b2e712a..bad6846ef29 100644 --- a/go/vt/vtctl/reparentutil/durability.go +++ b/go/vt/vtctl/reparentutil/policy/durability.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package reparentutil +package policy import ( "fmt" @@ -37,32 +37,47 @@ var ( durabilityPolicies = make(map[string]NewDurabler) ) +const ( + // DurabilityNone is the name of the durability policy that has no semi-sync setup. + DurabilityNone = "none" + // DurabilitySemiSync is the name of the durability policy that has 1 semi-sync setup. + DurabilitySemiSync = "semi_sync" + // DurabilityCrossCell is the name of the durability policy that has 1 semi-sync setup but only allows Primary and Replica type servers from a different cell to acknowledge semi sync. + DurabilityCrossCell = "cross_cell" + // DurabilitySemiSyncWithRdonlyAck is the name of the durability policy that has 1 semi-sync setup and allows the "rdonly" to send semi-sync acks as well. + DurabilitySemiSyncWithRdonlyAck = "semi_sync_with_rdonly_ack" + // DurabilityCrossCellWithRdonlyAck is the name of the durability policy that has 1 semi-sync setup but only allows Primary and Replica type servers from a different cell to acknowledge semi sync. It also allows the "rdonly" to send semi-sync acks. + DurabilityCrossCellWithRdonlyAck = "cross_cell_with_rdonly_ack" + // DurabilityTest is the name of the durability policy that has no semi-sync setup but overrides the type for a specific tablet to prefer. It is only meant to be used for testing purposes! + DurabilityTest = "test" +) + func init() { // register all the durability rules with their functions to create them - RegisterDurability("none", func() Durabler { + RegisterDurability(DurabilityNone, func() Durabler { return &durabilityNone{} }) - RegisterDurability("semi_sync", func() Durabler { + RegisterDurability(DurabilitySemiSync, func() Durabler { return &durabilitySemiSync{ rdonlySemiSync: false, } }) - RegisterDurability("cross_cell", func() Durabler { + RegisterDurability(DurabilityCrossCell, func() Durabler { return &durabilityCrossCell{ rdonlySemiSync: false, } }) - RegisterDurability("semi_sync_with_rdonly_ack", func() Durabler { + RegisterDurability(DurabilitySemiSyncWithRdonlyAck, func() Durabler { return &durabilitySemiSync{ rdonlySemiSync: true, } }) - RegisterDurability("cross_cell_with_rdonly_ack", func() Durabler { + RegisterDurability(DurabilityCrossCellWithRdonlyAck, func() Durabler { return &durabilityCrossCell{ rdonlySemiSync: true, } }) - RegisterDurability("test", func() Durabler { + RegisterDurability(DurabilityTest, func() Durabler { return &durabilityTest{} }) } diff --git a/go/vt/vtctl/reparentutil/durability_test.go b/go/vt/vtctl/reparentutil/policy/durability_test.go similarity index 97% rename from go/vt/vtctl/reparentutil/durability_test.go rename to go/vt/vtctl/reparentutil/policy/durability_test.go index 5745da64f7e..441275f29bf 100644 --- a/go/vt/vtctl/reparentutil/durability_test.go +++ b/go/vt/vtctl/reparentutil/policy/durability_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package reparentutil +package policy import ( "testing" @@ -29,7 +29,7 @@ import ( ) func TestDurabilityNone(t *testing.T) { - durability, err := GetDurabilityPolicy("none") + durability, err := GetDurabilityPolicy(DurabilityNone) require.NoError(t, err) promoteRule := PromotionRule(durability, &topodatapb.Tablet{ @@ -78,10 +78,10 @@ func TestDurabilitySemiSync(t *testing.T) { rdonlySemiSync bool }{ { - durabilityPolicy: "semi_sync", + durabilityPolicy: DurabilitySemiSync, rdonlySemiSync: false, }, { - durabilityPolicy: "semi_sync_with_rdonly_ack", + durabilityPolicy: DurabilitySemiSyncWithRdonlyAck, rdonlySemiSync: true, }, } @@ -176,10 +176,10 @@ func TestDurabilityCrossCell(t *testing.T) { rdonlySemiSync bool }{ { - durabilityPolicy: "cross_cell", + durabilityPolicy: DurabilityCrossCell, rdonlySemiSync: false, }, { - durabilityPolicy: "cross_cell_with_rdonly_ack", + durabilityPolicy: DurabilityCrossCellWithRdonlyAck, rdonlySemiSync: true, }, } diff --git a/go/vt/vtctl/reparentutil/reparent_sorter.go b/go/vt/vtctl/reparentutil/reparent_sorter.go index ea7367bd36b..2f9c3c9ea8d 100644 --- a/go/vt/vtctl/reparentutil/reparent_sorter.go +++ b/go/vt/vtctl/reparentutil/reparent_sorter.go @@ -20,6 +20,7 @@ import ( "sort" "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vterrors" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -32,11 +33,11 @@ type reparentSorter struct { tablets []*topodatapb.Tablet positions []replication.Position innodbBufferPool []int - durability Durabler + durability policy.Durabler } // newReparentSorter creates a new reparentSorter -func newReparentSorter(tablets []*topodatapb.Tablet, positions []replication.Position, innodbBufferPool []int, durability Durabler) *reparentSorter { +func newReparentSorter(tablets []*topodatapb.Tablet, positions []replication.Position, innodbBufferPool []int, durability policy.Durabler) *reparentSorter { return &reparentSorter{ tablets: tablets, positions: positions, @@ -82,8 +83,8 @@ func (rs *reparentSorter) Less(i, j int) bool { // at this point, both have the same GTIDs // so we check their promotion rules - jPromotionRule := PromotionRule(rs.durability, rs.tablets[j]) - iPromotionRule := PromotionRule(rs.durability, rs.tablets[i]) + jPromotionRule := policy.PromotionRule(rs.durability, rs.tablets[j]) + iPromotionRule := policy.PromotionRule(rs.durability, rs.tablets[i]) // If the promotion rules are different then we want to sort by the promotion rules. if len(rs.innodbBufferPool) != 0 && jPromotionRule == iPromotionRule { @@ -100,7 +101,7 @@ func (rs *reparentSorter) Less(i, j int) bool { // sortTabletsForReparent sorts the tablets, given their positions for emergency reparent shard and planned reparent shard. // Tablets are sorted first by their replication positions, with ties broken by the promotion rules. -func sortTabletsForReparent(tablets []*topodatapb.Tablet, positions []replication.Position, innodbBufferPool []int, durability Durabler) error { +func sortTabletsForReparent(tablets []*topodatapb.Tablet, positions []replication.Position, innodbBufferPool []int, durability policy.Durabler) error { // throw an error internal error in case of unequal number of tablets and positions // fail-safe code prevents panic in sorting in case the lengths are unequal if len(tablets) != len(positions) { diff --git a/go/vt/vtctl/reparentutil/reparent_sorter_test.go b/go/vt/vtctl/reparentutil/reparent_sorter_test.go index 87e7b253d54..86aa129f1a4 100644 --- a/go/vt/vtctl/reparentutil/reparent_sorter_test.go +++ b/go/vt/vtctl/reparentutil/reparent_sorter_test.go @@ -23,6 +23,7 @@ import ( "vitess.io/vitess/go/mysql/replication" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" ) // TestReparentSorter tests that the sorting for tablets works correctly @@ -135,7 +136,7 @@ func TestReparentSorter(t *testing.T) { }, } - durability, err := GetDurabilityPolicy("none") + durability, err := policy.GetDurabilityPolicy(policy.DurabilityNone) require.NoError(t, err) for _, testcase := range testcases { t.Run(testcase.name, func(t *testing.T) { diff --git a/go/vt/vtctl/reparentutil/replication.go b/go/vt/vtctl/reparentutil/replication.go index e7919361a09..1e1c2b98369 100644 --- a/go/vt/vtctl/reparentutil/replication.go +++ b/go/vt/vtctl/reparentutil/replication.go @@ -35,6 +35,7 @@ import ( "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/topotools/events" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tmclient" ) @@ -153,12 +154,12 @@ func SetReplicationSource(ctx context.Context, ts *topo.Server, tmc tmclient.Tab return err } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return err } - isSemiSync := IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet) + isSemiSync := policy.IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet) return tmc.SetReplicationSource(ctx, tablet, shardPrimary.Alias, 0, "", false, isSemiSync, 0) } @@ -183,7 +184,7 @@ func stopReplicationAndBuildStatusMaps( stopReplicationTimeout time.Duration, ignoredTablets sets.Set[string], tabletToWaitFor *topodatapb.TabletAlias, - durability Durabler, + durability policy.Durabler, waitForAllTablets bool, logger logutil.Logger, ) (*replicationSnapshot, error) { @@ -216,9 +217,6 @@ func stopReplicationAndBuildStatusMaps( logger.Infof("getting replication position from %v", alias) stopReplicationStatus, err := tmc.StopReplicationAndGetStatus(groupCtx, tabletInfo.Tablet, replicationdatapb.StopReplicationMode_IOTHREADONLY) - m.Lock() - res.tabletsBackupState[alias] = stopReplicationStatus.GetBackupRunning() - m.Unlock() if err != nil { sqlErr, isSQLErr := sqlerror.NewSQLErrorFromError(err).(*sqlerror.SQLError) if isSQLErr && sqlErr != nil && sqlErr.Number() == sqlerror.ERNotReplica { @@ -242,6 +240,20 @@ func stopReplicationAndBuildStatusMaps( err = vterrors.Wrapf(err, "error when getting replication status for alias %v: %v", alias, err) } } else { + isTakingBackup := false + + // Prefer the most up-to-date information regarding whether the tablet is taking a backup from the After + // replication status, but fall back to the Before status if After is nil. + if stopReplicationStatus.After != nil { + isTakingBackup = stopReplicationStatus.After.BackupRunning + } else if stopReplicationStatus.Before != nil { + isTakingBackup = stopReplicationStatus.Before.BackupRunning + } + + m.Lock() + res.tabletsBackupState[alias] = isTakingBackup + m.Unlock() + var sqlThreadRunning bool // Check if the sql thread was running for the tablet sqlThreadRunning, err = SQLThreadWasRunning(stopReplicationStatus) diff --git a/go/vt/vtctl/reparentutil/replication_test.go b/go/vt/vtctl/reparentutil/replication_test.go index 4a449b1189c..1f8e5d097b7 100644 --- a/go/vt/vtctl/reparentutil/replication_test.go +++ b/go/vt/vtctl/reparentutil/replication_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" _flag "vitess.io/vitess/go/internal/flag" "vitess.io/vitess/go/mysql" @@ -283,12 +284,13 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { waitForAllTablets bool expectedStatusMap map[string]*replicationdatapb.StopReplicationStatus expectedPrimaryStatusMap map[string]*replicationdatapb.PrimaryStatus + expectedTakingBackup map[string]bool expectedTabletsReachable []*topodatapb.Tablet shouldErr bool }{ { name: "success", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -339,6 +341,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000100": false, "zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, expectedTabletsReachable: []*topodatapb.Tablet{{ Type: topodatapb.TabletType_REPLICA, @@ -356,7 +359,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { shouldErr: false, }, { name: "success with wait for all tablets", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -407,6 +410,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000100": false, "zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, expectedTabletsReachable: []*topodatapb.Tablet{{ Type: topodatapb.TabletType_REPLICA, @@ -425,7 +429,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { shouldErr: false, }, { name: "timing check with wait for all tablets", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -491,6 +495,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000100": false, "zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, expectedTabletsReachable: []*topodatapb.Tablet{{ Type: topodatapb.TabletType_REPLICA, @@ -510,7 +515,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "success - 2 rdonly failures", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -585,6 +590,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000100": false, "zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, expectedTabletsReachable: []*topodatapb.Tablet{{ Type: topodatapb.TabletType_REPLICA, @@ -603,7 +609,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "success - 1 rdonly and 1 replica failures", - durability: "semi_sync", + durability: policy.DurabilitySemiSync, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -678,6 +684,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000100": false, "zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, expectedTabletsReachable: []*topodatapb.Tablet{{ Type: topodatapb.TabletType_REPLICA, @@ -696,7 +703,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "ignore tablets", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -750,12 +757,13 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { Uid: 101, }, }}, + expectedTakingBackup: map[string]bool{"zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, shouldErr: false, }, { name: "have PRIMARY tablet and can demote", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ demotePrimaryResults: map[string]*struct { PrimaryStatus *replicationdatapb.PrimaryStatus @@ -811,6 +819,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{ "zone1-0000000100": { Position: "primary-position-100", @@ -833,7 +842,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "one tablet is PRIMARY and cannot demote", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ demotePrimaryResults: map[string]*struct { PrimaryStatus *replicationdatapb.PrimaryStatus @@ -885,6 +894,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, // zone1-0000000100 fails to demote, so does not appear expectedTabletsReachable: []*topodatapb.Tablet{{ Type: topodatapb.TabletType_REPLICA, @@ -897,7 +907,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "multiple tablets are PRIMARY and cannot demote", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ demotePrimaryResults: map[string]*struct { PrimaryStatus *replicationdatapb.PrimaryStatus @@ -950,7 +960,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "stopReplicasTimeout exceeded", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusDelays: map[string]time.Duration{ "zone1-0000000100": time.Minute, // zone1-0000000100 will timeout and not be included @@ -1008,12 +1018,13 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { Uid: 101, }, }}, + expectedTakingBackup: map[string]bool{"zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, shouldErr: false, }, { name: "one tablet fails to StopReplication", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -1057,6 +1068,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, }, }, + expectedTakingBackup: map[string]bool{"zone1-0000000101": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, expectedTabletsReachable: []*topodatapb.Tablet{{ Type: topodatapb.TabletType_REPLICA, @@ -1069,7 +1081,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "multiple tablets fail StopReplication", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -1110,7 +1122,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { shouldErr: true, }, { name: "1 tablets fail StopReplication and 1 has replication stopped", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { StopStatus *replicationdatapb.StopReplicationStatus @@ -1155,7 +1167,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, { name: "slow tablet is the new primary requested", - durability: "none", + durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusDelays: map[string]time.Duration{ "zone1-0000000102": 1 * time.Second, // zone1-0000000102 is slow to respond but has to be included since it is the requested primary @@ -1252,14 +1264,84 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, }}, stopReplicasTimeout: time.Minute, + expectedTakingBackup: map[string]bool{"zone1-0000000100": false, "zone1-0000000101": false, "zone1-0000000102": false}, expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, shouldErr: false, + }, { + name: "Handle nil replication status After. No segfaulting when determining backup status, and fall back to Before status", + durability: policy.DurabilityNone, + tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ + stopReplicationAndGetStatusResults: map[string]*struct { + StopStatus *replicationdatapb.StopReplicationStatus + Err error + }{ + "zone1-0000000100": { + StopStatus: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-5", IoState: int32(replication.ReplicationStateRunning), SqlState: int32(replication.ReplicationStateRunning), BackupRunning: true}, + After: nil, + }, + }, + "zone1-0000000101": { + StopStatus: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-5", IoState: int32(replication.ReplicationStateRunning), SqlState: int32(replication.ReplicationStateRunning), BackupRunning: true}, + After: nil, + }, + }, + }, + }, + tabletMap: map[string]*topo.TabletInfo{ + "zone1-0000000100": { + Tablet: &topodatapb.Tablet{ + Type: topodatapb.TabletType_REPLICA, + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + "zone1-0000000101": { + Tablet: &topodatapb.Tablet{ + Type: topodatapb.TabletType_REPLICA, + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + }, + }, + }, + ignoredTablets: sets.New[string](), + expectedStatusMap: map[string]*replicationdatapb.StopReplicationStatus{ + "zone1-0000000100": { + Before: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-5", IoState: int32(replication.ReplicationStateRunning), SqlState: int32(replication.ReplicationStateRunning), BackupRunning: true}, + After: nil, + }, + "zone1-0000000101": { + Before: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-5", IoState: int32(replication.ReplicationStateRunning), SqlState: int32(replication.ReplicationStateRunning), BackupRunning: true}, + After: nil, + }, + }, + expectedTakingBackup: map[string]bool{"zone1-0000000100": true, "zone1-0000000101": true}, + expectedPrimaryStatusMap: map[string]*replicationdatapb.PrimaryStatus{}, + expectedTabletsReachable: []*topodatapb.Tablet{{ + Type: topodatapb.TabletType_REPLICA, + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, { + Type: topodatapb.TabletType_REPLICA, + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + }}, + shouldErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - durability, err := GetDurabilityPolicy(tt.durability) + durability, err := policy.GetDurabilityPolicy(tt.durability) require.NoError(t, err) startTime := time.Now() res, err := stopReplicationAndBuildStatusMaps(ctx, tt.tmc, &events.Reparent{}, tt.tabletMap, tt.stopReplicasTimeout, tt.ignoredTablets, tt.tabletToWaitFor, durability, tt.waitForAllTablets, logger) @@ -1279,6 +1361,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { for idx, tablet := range res.reachableTablets { assert.True(t, topoproto.IsTabletInList(tablet, tt.expectedTabletsReachable), "TabletsReached[%d] not found - %s", idx, topoproto.TabletAliasString(tablet.Alias)) } + assert.Equal(t, tt.expectedTakingBackup, res.tabletsBackupState) }) } } diff --git a/go/vt/vtctl/reparentutil/util.go b/go/vt/vtctl/reparentutil/util.go index c4c23e65c7e..4b8a4cbc431 100644 --- a/go/vt/vtctl/reparentutil/util.go +++ b/go/vt/vtctl/reparentutil/util.go @@ -34,6 +34,7 @@ import ( "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtctl/reparentutil/promotionrule" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tmclient" @@ -345,9 +346,9 @@ func findCandidate( } // getTabletsWithPromotionRules gets the tablets with the given promotion rule from the list of tablets -func getTabletsWithPromotionRules(durability Durabler, tablets []*topodatapb.Tablet, rule promotionrule.CandidatePromotionRule) (res []*topodatapb.Tablet) { +func getTabletsWithPromotionRules(durability policy.Durabler, tablets []*topodatapb.Tablet, rule promotionrule.CandidatePromotionRule) (res []*topodatapb.Tablet) { for _, candidate := range tablets { - promotionRule := PromotionRule(durability, candidate) + promotionRule := policy.PromotionRule(durability, candidate) if promotionRule == rule { res = append(res, candidate) } diff --git a/go/vt/vtctl/reparentutil/util_test.go b/go/vt/vtctl/reparentutil/util_test.go index ac44da8175a..276bab2e443 100644 --- a/go/vt/vtctl/reparentutil/util_test.go +++ b/go/vt/vtctl/reparentutil/util_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/utils" @@ -1014,7 +1015,7 @@ zone1-0000000100 is not a replica`, }, } - durability, err := GetDurabilityPolicy("none") + durability, err := policy.GetDurabilityPolicy(policy.DurabilityNone) require.NoError(t, err) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1829,7 +1830,7 @@ func Test_getTabletsWithPromotionRules(t *testing.T) { filteredTablets: nil, }, } - durability, _ := GetDurabilityPolicy("none") + durability, _ := policy.GetDurabilityPolicy(policy.DurabilityNone) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res := getTabletsWithPromotionRules(durability, tt.tablets, tt.rule) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index d3803d14e1a..2bba7c85e2a 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -100,6 +100,7 @@ import ( "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/ptr" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/cmd/vtctldclient/cli" "vitess.io/vitess/go/flagutil" @@ -587,7 +588,7 @@ var commands = []commandGroup{ name: "ValidateSchemaKeyspace", method: commandValidateSchemaKeyspace, params: "[--exclude_tables=''] [--include-views] [--skip-no-primary] [--include-vschema] ", - help: "Validates that the schema on the primary tablet for shard 0 matches the schema on all of the other tablets in the keyspace.", + help: "Validates that the schema on the primary tablet for the first shard matches the schema on all of the other tablets in the keyspace.", }, { name: "ApplySchema", @@ -1818,7 +1819,7 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags keyspaceType := subFlags.String("keyspace_type", "", "Specifies the type of the keyspace") baseKeyspace := subFlags.String("base_keyspace", "", "Specifies the base keyspace for a snapshot keyspace") timestampStr := subFlags.String("snapshot_time", "", "Specifies the snapshot time for this keyspace") - durabilityPolicy := subFlags.String("durability-policy", "none", "Type of durability to enforce for this keyspace. Default is none. Possible values include 'semi_sync' and others as dictated by registered plugins.") + durabilityPolicy := subFlags.String("durability-policy", policy.DurabilityNone, "Type of durability to enforce for this keyspace. Default is none. Possible values include 'semi_sync' and others as dictated by registered plugins.") sidecarDBName := subFlags.String("sidecar-db-name", sidecar.DefaultName, "(Experimental) Name of the Vitess sidecar database that tablets in this keyspace will use for internal metadata.") if err := subFlags.Parse(args); err != nil { return err @@ -1840,7 +1841,7 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags var snapshotTime *vttime.Time if ktype == topodatapb.KeyspaceType_SNAPSHOT { - if *durabilityPolicy != "none" { + if *durabilityPolicy != policy.DurabilityNone { return vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "durability-policy cannot be specified while creating a snapshot keyspace") } if *baseKeyspace == "" { @@ -1885,31 +1886,35 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags } if ktype == topodatapb.KeyspaceType_SNAPSHOT { - // copy vschema from base keyspace - vs, err := wr.TopoServer().GetVSchema(ctx, *baseKeyspace) + // Copy vschema from the base keyspace. + bksvs, err := wr.TopoServer().GetVSchema(ctx, *baseKeyspace) + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: keyspace, + } if err != nil { wr.Logger().Infof("error from GetVSchema for base_keyspace: %v, %v", *baseKeyspace, err) if topo.IsErrType(err, topo.NoNode) { - vs = &vschemapb.Keyspace{ - Sharded: false, - Tables: make(map[string]*vschemapb.Table), - Vindexes: make(map[string]*vschemapb.Vindex), - RequireExplicitRouting: true, + // Create an empty vschema for the keyspace. + ksvs.Keyspace = &vschemapb.Keyspace{ + Sharded: false, + Tables: make(map[string]*vschemapb.Table), + Vindexes: make(map[string]*vschemapb.Vindex), } } else { return err } - } else { - // SNAPSHOT keyspaces are excluded from global routing. - vs.RequireExplicitRouting = true } - if err := wr.TopoServer().SaveVSchema(ctx, keyspace, vs); err != nil { - wr.Logger().Infof("error from SaveVSchema %v:%v", vs, err) + // Copy the vschema from the base keyspace to the new one. + ksvs.Keyspace = bksvs.Keyspace.CloneVT() + // SNAPSHOT keyspaces are excluded from global routing. + ksvs.RequireExplicitRouting = true + if err := wr.TopoServer().SaveVSchema(ctx, ksvs); err != nil { + wr.Logger().Infof("error from SaveVSchema %v:%v", ksvs, err) return err } } - return wr.TopoServer().RebuildSrvVSchema(ctx, []string{} /* cells */) + return wr.TopoServer().RebuildSrvVSchema(ctx, nil /* cells */) } func commandDeleteKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags *pflag.FlagSet, args []string) error { @@ -3343,7 +3348,7 @@ func commandApplyVSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *p } keyspace := subFlags.Arg(0) - var vs *vschemapb.Keyspace + var ksvs *topo.KeyspaceVSchemaInfo var err error sqlMode := (*sql != "") != (*sqlFile != "") @@ -3375,20 +3380,10 @@ func commandApplyVSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *p return fmt.Errorf("error parsing vschema statement `%s`: not a ddl statement", *sql) } - vs, err = wr.TopoServer().GetVSchema(ctx, keyspace) - if err != nil { - if topo.IsErrType(err, topo.NoNode) { - vs = &vschemapb.Keyspace{} - } else { - return err - } - } - - vs, err = topotools.ApplyVSchemaDDL(keyspace, vs, ddl) + ksvs, err = topotools.ApplyVSchemaDDL(ctx, keyspace, wr.TopoServer(), ddl) if err != nil { return err } - } else { // json mode var schema []byte @@ -3402,14 +3397,17 @@ func commandApplyVSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *p schema = []byte(*vschema) } - vs = &vschemapb.Keyspace{} - err := json2.UnmarshalPB(schema, vs) + ksvs = &topo.KeyspaceVSchemaInfo{ + Name: keyspace, + Keyspace: &vschemapb.Keyspace{}, + } + err := json2.UnmarshalPB(schema, ksvs.Keyspace) if err != nil { return err } } - b, err := json2.MarshalIndentPB(vs, " ") + b, err := json2.MarshalIndentPB(ksvs.Keyspace, " ") if err != nil { wr.Logger().Errorf2(err, "Failed to marshal VSchema for display") } else { @@ -3417,7 +3415,7 @@ func commandApplyVSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *p } // Validate the VSchema. - ksVs, err := vindexes.BuildKeyspace(vs, wr.SQLParser()) + ksVs, err := vindexes.BuildKeyspace(ksvs.Keyspace, wr.SQLParser()) if err != nil { return err } @@ -3449,11 +3447,11 @@ func commandApplyVSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *p return err } - if _, err := vindexes.BuildKeyspace(vs, wr.SQLParser()); err != nil { + if _, err := vindexes.BuildKeyspace(ksvs.Keyspace, wr.SQLParser()); err != nil { return err } - if err := wr.TopoServer().SaveVSchema(ctx, keyspace, vs); err != nil { + if err := wr.TopoServer().SaveVSchema(ctx, ksvs); err != nil { return err } diff --git a/go/vt/vtctl/workflow/framework_test.go b/go/vt/vtctl/workflow/framework_test.go index d84d1236075..fad48e31e0c 100644 --- a/go/vt/vtctl/workflow/framework_test.go +++ b/go/vt/vtctl/workflow/framework_test.go @@ -272,7 +272,7 @@ type testTMClient struct { createVReplicationWorkflowRequests map[uint32]*createVReplicationWorkflowRequestResponse readVReplicationWorkflowRequests map[uint32]*readVReplicationWorkflowRequestResponse updateVReplicationWorklowsRequests map[uint32]*tabletmanagerdatapb.UpdateVReplicationWorkflowsRequest - applySchemaRequests map[uint32]*applySchemaRequestResponse + applySchemaRequests map[uint32][]*applySchemaRequestResponse primaryPositions map[uint32]string vdiffRequests map[uint32]*vdiffRequestResponse refreshStateErrors map[uint32]error @@ -296,7 +296,7 @@ func newTestTMClient(env *testEnv) *testTMClient { createVReplicationWorkflowRequests: make(map[uint32]*createVReplicationWorkflowRequestResponse), readVReplicationWorkflowRequests: make(map[uint32]*readVReplicationWorkflowRequestResponse), updateVReplicationWorklowsRequests: make(map[uint32]*tabletmanagerdatapb.UpdateVReplicationWorkflowsRequest), - applySchemaRequests: make(map[uint32]*applySchemaRequestResponse), + applySchemaRequests: make(map[uint32][]*applySchemaRequestResponse), readVReplicationWorkflowsResponses: make(map[string][]*tabletmanagerdatapb.ReadVReplicationWorkflowsResponse), primaryPositions: make(map[uint32]string), vdiffRequests: make(map[uint32]*vdiffRequestResponse), @@ -398,10 +398,9 @@ func (tmc *testTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Table schemaDefn := &tabletmanagerdatapb.SchemaDefinition{} for _, table := range req.Tables { if table == "/.*/" { - // Special case of all tables in keyspace. - for key, tableDefn := range tmc.schema { + for key, schemaDefinition := range tmc.schema { if strings.HasPrefix(key, tablet.Keyspace+".") { - schemaDefn.TableDefinitions = append(schemaDefn.TableDefinitions, tableDefn.TableDefinitions...) + schemaDefn.TableDefinitions = append(schemaDefn.TableDefinitions, schemaDefinition.TableDefinitions...) } } break @@ -414,6 +413,12 @@ func (tmc *testTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Table } schemaDefn.TableDefinitions = append(schemaDefn.TableDefinitions, tableDefn.TableDefinitions...) } + for key, schemaDefinition := range tmc.schema { + if strings.HasPrefix(key, tablet.Keyspace) { + schemaDefn.DatabaseSchema = schemaDefinition.DatabaseSchema + break + } + } return schemaDefn, nil } @@ -498,15 +503,20 @@ func (tmc *testTMClient) ExecuteFetchAsAllPrivs(ctx context.Context, tablet *top return nil, nil } +func (tmc *testTMClient) ExecuteFetchAsApp(ctx context.Context, tablet *topodatapb.Tablet, usePool bool, req *tabletmanagerdatapb.ExecuteFetchAsAppRequest) (*querypb.QueryResult, error) { + // Reuse VReplicationExec. + return tmc.VReplicationExec(ctx, tablet, string(req.Query)) +} + func (tmc *testTMClient) expectApplySchemaRequest(tabletID uint32, req *applySchemaRequestResponse) { tmc.mu.Lock() defer tmc.mu.Unlock() if tmc.applySchemaRequests == nil { - tmc.applySchemaRequests = make(map[uint32]*applySchemaRequestResponse) + tmc.applySchemaRequests = make(map[uint32][]*applySchemaRequestResponse) } - tmc.applySchemaRequests[tabletID] = req + tmc.applySchemaRequests[tabletID] = append(tmc.applySchemaRequests[tabletID], req) } // Note: ONLY breaks up change.SQL into individual statements and executes it. Does NOT fully implement ApplySchema. @@ -514,11 +524,17 @@ func (tmc *testTMClient) ApplySchema(ctx context.Context, tablet *topodatapb.Tab tmc.mu.Lock() defer tmc.mu.Unlock() - if expect, ok := tmc.applySchemaRequests[tablet.Alias.Uid]; ok { + if requests, ok := tmc.applySchemaRequests[tablet.Alias.Uid]; ok { + if len(requests) == 0 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected ApplySchema request on tablet %s: got %+v", + topoproto.TabletAliasString(tablet.Alias), change) + } + expect := requests[0] if !reflect.DeepEqual(change, expect.change) { return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected ApplySchema request on tablet %s: got %+v, want %+v", topoproto.TabletAliasString(tablet.Alias), change, expect.change) } + tmc.applySchemaRequests[tablet.Alias.Uid] = tmc.applySchemaRequests[tablet.Alias.Uid][1:] return expect.res, expect.err } @@ -619,6 +635,10 @@ func (tmc *testTMClient) HasVReplicationWorkflows(ctx context.Context, tablet *t }, nil } +func (tmc *testTMClient) ResetSequences(ctx context.Context, tablet *topodatapb.Tablet, tables []string) error { + return nil +} + func (tmc *testTMClient) ReadVReplicationWorkflows(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ReadVReplicationWorkflowsRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowsResponse, error) { tmc.mu.Lock() defer tmc.mu.Unlock() @@ -770,6 +790,10 @@ func (tmc *testTMClient) getVReplicationWorkflowsResponse(key string) *tabletman return resp } +func (tmc *testTMClient) ReloadSchema(ctx context.Context, tablet *topodatapb.Tablet, waitPosition string) error { + return nil +} + // // Utility / helper functions. // diff --git a/go/vt/vtctl/workflow/lookup_vindex.go b/go/vt/vtctl/workflow/lookup_vindex.go new file mode 100644 index 00000000000..157dba083b0 --- /dev/null +++ b/go/vt/vtctl/workflow/lookup_vindex.go @@ -0,0 +1,597 @@ +/* +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" + "slices" + "strings" + + "golang.org/x/exp/maps" + "google.golang.org/protobuf/proto" + + "vitess.io/vitess/go/sqlescape" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/schema" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtctl/schematools" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tmclient" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" +) + +// lookupVindex is responsible for performing actions related to lookup vindexes. +type lookupVindex struct { + ts *topo.Server + tmc tmclient.TabletManagerClient + + logger logutil.Logger + parser *sqlparser.Parser +} + +// newLookupVindex creates a new lookupVindex instance which is responsible +// for performing actions related to lookup vindexes. +func newLookupVindex(ws *Server) *lookupVindex { + return &lookupVindex{ + ts: ws.ts, + tmc: ws.tmc, + logger: ws.Logger(), + parser: ws.SQLParser(), + } +} + +// prepareCreate performs the preparatory steps for creating a Lookup Vindex. +func (lv *lookupVindex) prepareCreate(ctx context.Context, workflow, keyspace string, specs *vschemapb.Keyspace, continueAfterCopyWithOwner bool) ( + ms *vtctldatapb.MaterializeSettings, sourceVSchema, targetVSchema *topo.KeyspaceVSchemaInfo, cancelFunc func() error, err error) { + var ( + // sourceVSchemaTable is the table info present in the vschema. + sourceVSchemaTable *vschemapb.Table + // sourceVindexColumns are computed from the input sourceTable. + sourceVindexColumns []string + + // Target table info. + createDDL string + materializeQuery string + ) + + // Validate input vindex. + vindex, vInfo, err := lv.validateAndGetVindex(specs) + if err != nil { + return nil, nil, nil, nil, err + } + + vInfo.sourceTable, vInfo.sourceTableName, err = getSourceTable(specs, vInfo.targetTableName, vInfo.fromCols) + if err != nil { + return nil, nil, nil, nil, err + } + + sourceVindexColumns, err = validateSourceTableAndGetVindexColumns(vInfo, vindex, keyspace) + if err != nil { + return nil, nil, nil, nil, err + } + + sourceVSchema, targetVSchema, err = lv.getTargetAndSourceVSchema(ctx, keyspace, vInfo.targetKeyspace) + if err != nil { + return nil, nil, nil, nil, err + } + + if existing, ok := sourceVSchema.Vindexes[vInfo.name]; ok { + if !proto.Equal(existing, vindex) { // If the exact same vindex already exists then we can re-use it + return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "a conflicting vindex named %s already exists in the %s keyspace", + vInfo.name, keyspace) + } + } + + sourceVSchemaTable = sourceVSchema.Tables[vInfo.sourceTableName] + if sourceVSchemaTable == nil && !schema.IsInternalOperationTableName(vInfo.sourceTableName) { + return nil, nil, nil, nil, + vterrors.Errorf(vtrpcpb.Code_INTERNAL, "table %s not found in the %s keyspace", vInfo.sourceTableName, keyspace) + } + if err := validateNonConflictingColumnVindex(sourceVSchemaTable, vInfo, sourceVindexColumns, keyspace); err != nil { + return nil, nil, nil, nil, err + } + + // Validate against source schema. + sourceShards, err := lv.ts.GetServingShards(ctx, keyspace) + if err != nil { + return nil, nil, nil, nil, err + } + onesource := sourceShards[0] + if onesource.PrimaryAlias == nil { + return nil, nil, nil, nil, + vterrors.Errorf(vtrpcpb.Code_INTERNAL, "source shard %s has no primary", onesource.ShardName()) + } + + req := &tabletmanagerdatapb.GetSchemaRequest{Tables: []string{vInfo.sourceTableName}} + tableSchema, err := schematools.GetSchema(ctx, lv.ts, lv.tmc, onesource.PrimaryAlias, req) + if err != nil { + return nil, nil, nil, nil, err + } + if len(tableSchema.TableDefinitions) != 1 { + return nil, nil, nil, nil, + vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected number of tables (%d) returned from %s schema", + len(tableSchema.TableDefinitions), keyspace) + } + + // Generate "create table" statement. + createDDL, err = lv.generateCreateDDLStatement(tableSchema, sourceVindexColumns, vInfo, vindex) + if err != nil { + return nil, nil, nil, nil, err + } + + // Generate vreplication query. + materializeQuery = generateMaterializeQuery(vInfo, vindex, sourceVindexColumns) + + // Save a copy of the original vschema if we modify it and need to provide + // a cancelFunc. We do NOT want to clone the key version as we explicitly + // want to go back in time. So we only clone the internal vschema.Keyspace. + origTargetVSchema := &topo.KeyspaceVSchemaInfo{ + Name: vInfo.targetKeyspace, + Keyspace: targetVSchema.Keyspace.CloneVT(), + } + targetChanged := false + + // Update targetVSchema. + targetTable := specs.Tables[vInfo.targetTableName] + if targetVSchema.Sharded { + // Choose a primary vindex type for the lookup table based on the source + // definition if one was not explicitly specified. + var targetVindexType string + var targetVindex *vschemapb.Vindex + for _, field := range tableSchema.TableDefinitions[0].Fields { + if sourceVindexColumns[0] == field.Name { + if targetTable != nil && len(targetTable.ColumnVindexes) > 0 { + targetVindexType = targetTable.ColumnVindexes[0].Name + } + if targetVindexType == "" { + targetVindexType, err = vindexes.ChooseVindexForType(field.Type) + if err != nil { + return nil, nil, nil, nil, err + } + } + targetVindex = &vschemapb.Vindex{ + Type: targetVindexType, + } + break + } + } + if targetVindex == nil { + // Unreachable. We validated column names when generating the DDL. + return nil, nil, nil, nil, + vterrors.Errorf(vtrpcpb.Code_INTERNAL, "column %s not found in target schema %s", + sourceVindexColumns[0], tableSchema.TableDefinitions[0].Schema) + } + + if existing, ok := targetVSchema.Vindexes[targetVindexType]; ok { + if !proto.Equal(existing, targetVindex) { + return nil, nil, nil, nil, + vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "a conflicting vindex named %v already exists in the %s keyspace", + targetVindexType, vInfo.targetKeyspace) + } + } else { + targetVSchema.Vindexes[targetVindexType] = targetVindex + targetChanged = true + } + + targetTable = &vschemapb.Table{ + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: vInfo.fromCols[0], + Name: targetVindexType, + }}, + } + } else { + targetTable = &vschemapb.Table{} + } + if existing, ok := targetVSchema.Tables[vInfo.targetTableName]; ok { + if !proto.Equal(existing, targetTable) { + return nil, nil, nil, nil, + vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "a conflicting table named %s already exists in the %s vschema", + vInfo.targetTableName, vInfo.targetKeyspace) + } + } else { + targetVSchema.Tables[vInfo.targetTableName] = targetTable + targetChanged = true + } + + if targetChanged { + cancelFunc = func() error { + // Restore the original target vschema. + return lv.ts.SaveVSchema(ctx, origTargetVSchema) + } + } + + ms = &vtctldatapb.MaterializeSettings{ + Workflow: workflow, + MaterializationIntent: vtctldatapb.MaterializationIntent_CREATELOOKUPINDEX, + SourceKeyspace: keyspace, + TargetKeyspace: vInfo.targetKeyspace, + StopAfterCopy: vindex.Owner != "" && !continueAfterCopyWithOwner, + TableSettings: []*vtctldatapb.TableMaterializeSettings{{ + TargetTable: vInfo.targetTableName, + SourceExpression: materializeQuery, + CreateDdl: createDDL, + }}, + } + + // Update sourceVSchema + sourceVSchema.Vindexes[vInfo.name] = vindex + sourceVSchemaTable.ColumnVindexes = append(sourceVSchemaTable.ColumnVindexes, vInfo.sourceTable.ColumnVindexes[0]) + + return ms, sourceVSchema, targetVSchema, cancelFunc, nil +} + +// vindexInfo holds the validated vindex configuration +type vindexInfo struct { + name string + targetKeyspace string + targetTableName string + fromCols []string + toCol string + ignoreNulls bool + + // sourceTable is the supplied table info. + sourceTable *vschemapb.Table + sourceTableName string +} + +// validateAndGetVindex validates and extracts vindex configuration +func (lv *lookupVindex) validateAndGetVindex(specs *vschemapb.Keyspace) (*vschemapb.Vindex, *vindexInfo, error) { + if specs == nil { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "no vindex provided") + } + if len(specs.Vindexes) != 1 { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "only one vindex must be specified") + } + + vindexName := maps.Keys(specs.Vindexes)[0] + vindex := maps.Values(specs.Vindexes)[0] + + if !strings.Contains(vindex.Type, "lookup") { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "vindex %s is not a lookup type", vindex.Type) + } + + targetKeyspace, targetTableName, err := lv.parser.ParseTable(vindex.Params["table"]) + if err != nil || targetKeyspace == "" { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, + "vindex table name (%s) must be in the form .", vindex.Params["table"]) + } + + vindexFromCols := strings.Split(vindex.Params["from"], ",") + for i, col := range vindexFromCols { + vindexFromCols[i] = strings.TrimSpace(col) + } + + if strings.Contains(vindex.Type, "unique") { + if len(vindexFromCols) != 1 { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unique vindex 'from' should have only one column") + } + } + + vindexToCol := vindex.Params["to"] + // Make the vindex write_only. If one exists already in the vschema, + // it will need to match this vindex exactly, including the write_only setting. + vindex.Params["write_only"] = "true" + + // See if we can create the vindex without errors. + if _, err := vindexes.CreateVindex(vindex.Type, vindexName, vindex.Params); err != nil { + return nil, nil, err + } + + ignoreNulls := false + if ignoreNullsStr, ok := vindex.Params["ignore_nulls"]; ok { + // This mirrors the behavior of vindexes.boolFromMap(). + switch ignoreNullsStr { + case "true": + ignoreNulls = true + case "false": + ignoreNulls = false + default: + return nil, nil, + vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "ignore_nulls (%s) value must be 'true' or 'false'", + ignoreNullsStr) + } + } + + // Validate input table. + if len(specs.Tables) < 1 || len(specs.Tables) > 2 { + return nil, nil, fmt.Errorf("one or two tables must be specified") + } + + return vindex, &vindexInfo{ + name: vindexName, + targetKeyspace: targetKeyspace, + targetTableName: targetTableName, + fromCols: vindexFromCols, + toCol: vindexToCol, + ignoreNulls: ignoreNulls, + }, nil +} + +func (lv *lookupVindex) getTargetAndSourceVSchema(ctx context.Context, sourceKeyspace, targetKeyspace string) (sourceVSchema, targetVSchema *topo.KeyspaceVSchemaInfo, err error) { + sourceVSchema, err = lv.ts.GetVSchema(ctx, sourceKeyspace) + if err != nil { + return nil, nil, err + } + if sourceVSchema.Vindexes == nil { + sourceVSchema.Vindexes = make(map[string]*vschemapb.Vindex) + } + // If source and target keyspaces are the same, make vschemas point + // to the same object. + if sourceKeyspace == targetKeyspace { + targetVSchema = sourceVSchema + } else { + targetVSchema, err = lv.ts.GetVSchema(ctx, targetKeyspace) + if err != nil { + return nil, nil, err + } + } + if targetVSchema.Vindexes == nil { + targetVSchema.Vindexes = make(map[string]*vschemapb.Vindex) + } + if targetVSchema.Tables == nil { + targetVSchema.Tables = make(map[string]*vschemapb.Table) + } + + return sourceVSchema, targetVSchema, nil +} + +func getSourceTable(specs *vschemapb.Keyspace, targetTableName string, fromCols []string) (sourceTable *vschemapb.Table, sourceTableName string, err error) { + // Loop executes once or twice. + for tableName, table := range specs.Tables { + if len(table.ColumnVindexes) != 1 { + return nil, "", vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "exactly one ColumnVindex must be specified for the %s table", + tableName) + } + + if tableName != targetTableName { // This is the source table. + sourceTableName = tableName + sourceTable = table + continue + } + // This is a primary vindex definition for the target table + // which allows you to override the vindex type used. + var vindexCols []string + if len(table.ColumnVindexes[0].Columns) != 0 { + vindexCols = table.ColumnVindexes[0].Columns + } else { + if table.ColumnVindexes[0].Column == "" { + return nil, "", vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "at least one column must be specified in ColumnVindexes for the %s table", + tableName) + } + vindexCols = []string{table.ColumnVindexes[0].Column} + } + if !slices.Equal(vindexCols, fromCols) { + return nil, "", vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "columns in the lookup table %s primary vindex (%s) don't match the 'from' columns specified (%s)", + tableName, strings.Join(vindexCols, ","), strings.Join(fromCols, ",")) + } + } + return sourceTable, sourceTableName, nil +} + +func (lv *lookupVindex) generateCreateDDLStatement(tableSchema *tabletmanagerdatapb.SchemaDefinition, sourceVindexColumns []string, vInfo *vindexInfo, vindex *vschemapb.Vindex) (string, error) { + lines := strings.Split(tableSchema.TableDefinitions[0].Schema, "\n") + if len(lines) < 3 { + // Should never happen. + return "", vterrors.Errorf(vtrpcpb.Code_INTERNAL, "schema looks incorrect: %s, expecting at least four lines", + tableSchema.TableDefinitions[0].Schema) + } + + var modified []string + modified = append(modified, strings.Replace(lines[0], vInfo.sourceTableName, vInfo.targetTableName, 1)) + for i := range sourceVindexColumns { + line, err := generateColDef(lines, sourceVindexColumns[i], vInfo.fromCols[i]) + if err != nil { + return "", err + } + modified = append(modified, line) + } + + if vindex.Params["data_type"] == "" || strings.EqualFold(vindex.Type, "consistent_lookup_unique") || strings.EqualFold(vindex.Type, "consistent_lookup") { + modified = append(modified, fmt.Sprintf(" %s varbinary(128),", sqlescape.EscapeID(vInfo.toCol))) + } else { + modified = append(modified, fmt.Sprintf(" %s %s,", sqlescape.EscapeID(vInfo.toCol), sqlescape.EscapeID(vindex.Params["data_type"]))) + } + + buf := sqlparser.NewTrackedBuffer(nil) + fmt.Fprintf(buf, " PRIMARY KEY (") + prefix := "" + for _, col := range vInfo.fromCols { + fmt.Fprintf(buf, "%s%s", prefix, sqlescape.EscapeID(col)) + prefix = ", " + } + fmt.Fprintf(buf, ")") + + modified = append(modified, buf.String()) + modified = append(modified, ")") + createDDL := strings.Join(modified, "\n") + + // Confirm that our DDL is valid before we create anything. + if _, err := lv.parser.ParseStrictDDL(createDDL); err != nil { + return "", vterrors.Errorf(vtrpcpb.Code_INTERNAL, "error: %v; invalid lookup table definition generated: %s", + err, createDDL) + } + + return createDDL, nil +} + +func generateMaterializeQuery(vInfo *vindexInfo, vindex *vschemapb.Vindex, sourceVindexColumns []string) string { + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("select ") + for i := range vInfo.fromCols { + buf.Myprintf("%s as %s, ", sqlparser.String(sqlparser.NewIdentifierCI(sourceVindexColumns[i])), sqlparser.String(sqlparser.NewIdentifierCI(vInfo.fromCols[i]))) + } + if strings.EqualFold(vInfo.toCol, "keyspace_id") || strings.EqualFold(vindex.Type, "consistent_lookup_unique") || strings.EqualFold(vindex.Type, "consistent_lookup") { + buf.Myprintf("keyspace_id() as %s ", sqlparser.String(sqlparser.NewIdentifierCI(vInfo.toCol))) + } else { + buf.Myprintf("%s as %s ", sqlparser.String(sqlparser.NewIdentifierCI(vInfo.toCol)), sqlparser.String(sqlparser.NewIdentifierCI(vInfo.toCol))) + } + buf.Myprintf("from %s", sqlparser.String(sqlparser.NewIdentifierCS(vInfo.sourceTableName))) + if vInfo.ignoreNulls { + buf.Myprintf(" where ") + lastValIdx := len(vInfo.fromCols) - 1 + for i := range vInfo.fromCols { + buf.Myprintf("%s is not null", sqlparser.String(sqlparser.NewIdentifierCI(vInfo.fromCols[i]))) + if i != lastValIdx { + buf.Myprintf(" and ") + } + } + } + if vindex.Owner != "" { + // Only backfill. + buf.Myprintf(" group by ") + for i := range vInfo.fromCols { + buf.Myprintf("%s, ", sqlparser.String(sqlparser.NewIdentifierCI(vInfo.fromCols[i]))) + } + buf.Myprintf("%s", sqlparser.String(sqlparser.NewIdentifierCI(vInfo.toCol))) + } + return buf.String() +} + +// validateSourceTableAndGetVindexColumns validates input table and vindex consistency, and returns sourceVindexColumns. +func validateSourceTableAndGetVindexColumns(vInfo *vindexInfo, vindex *vschemapb.Vindex, keyspace string) (sourceVindexColumns []string, err error) { + if vInfo.sourceTable == nil || len(vInfo.sourceTable.ColumnVindexes) != 1 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "No ColumnVindex found for the owner table (%s) in the %s keyspace", + vInfo.sourceTable, keyspace) + } + if vInfo.sourceTable.ColumnVindexes[0].Name != vInfo.name { + return nil, + vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "ColumnVindex name (%s) must match vindex name (%s)", + vInfo.sourceTable.ColumnVindexes[0].Name, vInfo.name) + } + if vindex.Owner != "" && vindex.Owner != vInfo.sourceTableName { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "vindex owner (%s) must match table name (%s)", + vindex.Owner, vInfo.sourceTableName) + } + if len(vInfo.sourceTable.ColumnVindexes[0].Columns) != 0 { + sourceVindexColumns = vInfo.sourceTable.ColumnVindexes[0].Columns + } else { + if vInfo.sourceTable.ColumnVindexes[0].Column == "" { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "at least one column must be specified in ColumnVindexes for the %s table", + vInfo.sourceTableName) + } + sourceVindexColumns = []string{vInfo.sourceTable.ColumnVindexes[0].Column} + } + if len(sourceVindexColumns) != len(vInfo.fromCols) { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "length of table columns (%d) differs from length of vindex columns (%d)", + len(sourceVindexColumns), len(vInfo.fromCols)) + } + + return sourceVindexColumns, nil +} + +func validateNonConflictingColumnVindex(sourceVSchemaTable *vschemapb.Table, vInfo *vindexInfo, sourceVindexColumns []string, keyspace string) error { + for _, colVindex := range sourceVSchemaTable.ColumnVindexes { + // For a conflict, the vindex name and column should match. + if colVindex.Name != vInfo.name { + continue + } + var colNames []string + if len(colVindex.Columns) == 0 { + colNames = []string{colVindex.Column} + } else { + colNames = colVindex.Columns + } + // If this is the exact same definition then we can use the existing one. If they + // are not the same then they are two distinct conflicting vindexes and we should + // not proceed. + if !slices.Equal(colNames, sourceVindexColumns) { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "a conflicting ColumnVindex on column(s) %s in table %s already exists in the %s keyspace", + strings.Join(colNames, ","), vInfo.sourceTableName, keyspace) + } + } + return nil +} + +func generateColDef(lines []string, sourceVindexCol, vindexFromCol string) (string, error) { + source := sqlescape.EscapeID(sourceVindexCol) + target := sqlescape.EscapeID(vindexFromCol) + + for _, line := range lines[1:] { + if strings.Contains(line, source) { + line = strings.Replace(line, source, target, 1) + line = strings.Replace(line, " AUTO_INCREMENT", "", 1) + line = strings.Replace(line, " DEFAULT NULL", "", 1) + // Ensure that the column definition ends with a comma as we will + // be appending the TO column and PRIMARY KEY definitions. If the + // souce column here was the last entity defined in the source + // table's definition then it will not already have the comma. + if !strings.HasSuffix(strings.TrimSpace(line), ",") { + line += "," + } + return line, nil + } + } + return "", fmt.Errorf("column %s not found in schema %v", sourceVindexCol, lines) +} + +// validateExternalizedVindex checks if a given vindex is externalized. +// A vindex is considered externalized if it has an owner and is not in write-only mode. +func (lv *lookupVindex) validateExternalizedVindex(vindex *vschemapb.Vindex) error { + writeOnly, ok := vindex.Params["write_only"] + if ok && writeOnly == "true" { + return fmt.Errorf("vindex is in write-only mode") + } + if vindex.Owner == "" { + return fmt.Errorf("vindex has no owner") + } + return nil +} + +// validateExternalized checks if the vindex has been externalized +// and verifies the state of the VReplication workflow on the target shards. +// It ensures that all streams in the workflow are frozen. +func (lv *lookupVindex) validateExternalized(ctx context.Context, vindex *vschemapb.Vindex, name string, targetShards []*topo.ShardInfo) error { + if err := lv.validateExternalizedVindex(vindex); err != nil { + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "vindex %s has not been externalized yet: %v", name, err) + } + + err := forAllShards(targetShards, func(targetShard *topo.ShardInfo) error { + targetPrimary, err := lv.ts.GetTablet(ctx, targetShard.PrimaryAlias) + if err != nil { + return err + } + res, err := lv.tmc.ReadVReplicationWorkflow(ctx, targetPrimary.Tablet, &tabletmanagerdatapb.ReadVReplicationWorkflowRequest{ + Workflow: name, + }) + if err != nil { + return err + } + if res == nil || res.Workflow == "" { + return vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "workflow %s not found on %v", name, topoproto.TabletAliasString(targetPrimary.Alias)) + } + for _, stream := range res.Streams { + // All streams need to be frozen. + if stream.State != binlogdatapb.VReplicationWorkflowState_Stopped || stream.Message != Frozen { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "stream %d for %v/%v is not frozen: %v, %v", stream.Id, targetShard.Keyspace(), targetShard.ShardName(), stream.State, stream.Message) + } + } + return nil + }) + if err != nil { + return err + } + return nil +} diff --git a/go/vt/vtctl/workflow/materializer.go b/go/vt/vtctl/workflow/materializer.go index c65a00bf614..8cd99d384ee 100644 --- a/go/vt/vtctl/workflow/materializer.go +++ b/go/vt/vtctl/workflow/materializer.go @@ -283,7 +283,7 @@ func (mz *materializer) deploySchema() error { // We do, however, allow the user to override this behavior and retain them. removeAutoInc := false updatedVSchema := false - var targetVSchema *vschemapb.Keyspace + var targetVSchema *topo.KeyspaceVSchemaInfo if mz.workflowType == binlogdatapb.VReplicationWorkflowType_MoveTables && (mz.targetVSchema != nil && mz.targetVSchema.Keyspace != nil && mz.targetVSchema.Keyspace.Sharded) && (mz.ms.GetWorkflowOptions() != nil && mz.ms.GetWorkflowOptions().ShardedAutoIncrementHandling != vtctldatapb.ShardedAutoIncrementHandling_LEAVE) { @@ -472,7 +472,7 @@ func (mz *materializer) deploySchema() error { } if updatedVSchema { - return mz.ts.SaveVSchema(mz.ctx, mz.ms.TargetKeyspace, targetVSchema) + return mz.ts.SaveVSchema(mz.ctx, targetVSchema) } return nil @@ -485,7 +485,7 @@ func (mz *materializer) buildMaterializer() error { if err != nil { return err } - targetVSchema, err := vindexes.BuildKeyspaceSchema(vschema, ms.TargetKeyspace, mz.env.Parser()) + targetVSchema, err := vindexes.BuildKeyspaceSchema(vschema.Keyspace, ms.TargetKeyspace, mz.env.Parser()) if err != nil { return err } @@ -563,7 +563,7 @@ func (mz *materializer) buildMaterializer() error { if err != nil { return fmt.Errorf("failed to get source keyspace vschema: %v", err) } - differentPVs = primaryVindexesDiffer(ms, sourceVSchema, vschema) + differentPVs = primaryVindexesDiffer(ms, sourceVSchema.Keyspace, vschema.Keyspace) mz.targetVSchema = targetVSchema mz.sourceShards = sourceShards diff --git a/go/vt/vtctl/workflow/materializer_env_test.go b/go/vt/vtctl/workflow/materializer_env_test.go index fb5064137cd..c7c66f4fd29 100644 --- a/go/vt/vtctl/workflow/materializer_env_test.go +++ b/go/vt/vtctl/workflow/materializer_env_test.go @@ -86,10 +86,10 @@ func newTestMaterializerEnv(t *testing.T, ctx context.Context, ms *vtctldatapb.M } require.NoError(t, topoServ.CreateKeyspace(ctx, ms.SourceKeyspace, &topodatapb.Keyspace{})) - require.NoError(t, topoServ.SaveVSchema(ctx, ms.SourceKeyspace, &vschemapb.Keyspace{})) + require.NoError(t, topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{Name: ms.SourceKeyspace, Keyspace: &vschemapb.Keyspace{}})) if ms.SourceKeyspace != ms.TargetKeyspace { require.NoError(t, topoServ.CreateKeyspace(ctx, ms.TargetKeyspace, &topodatapb.Keyspace{})) - require.NoError(t, topoServ.SaveVSchema(ctx, ms.TargetKeyspace, &vschemapb.Keyspace{})) + require.NoError(t, topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{Name: ms.TargetKeyspace, Keyspace: &vschemapb.Keyspace{}})) } logger := logutil.NewConsoleLogger() require.NoError(t, topoServ.RebuildSrvVSchema(ctx, []string{"cell"})) diff --git a/go/vt/vtctl/workflow/materializer_test.go b/go/vt/vtctl/workflow/materializer_test.go index 746c5fe2bae..c28beb933e8 100644 --- a/go/vt/vtctl/workflow/materializer_test.go +++ b/go/vt/vtctl/workflow/materializer_test.go @@ -497,7 +497,10 @@ func TestAddTablesToVSchema(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := ts.SaveVSchema(ctx, srcks, tt.sourceVSchema) + err := ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: srcks, + Keyspace: tt.sourceVSchema, + }) require.NoError(t, err) err = ws.addTablesToVSchema(ctx, srcks, tt.inTargetVSchema, tt.tables, tt.copyVSchema) require.NoError(t, err) @@ -910,7 +913,10 @@ func TestShardedAutoIncHandling(t *testing.T) { } if tc.targetVSchema != nil { - err := env.ws.ts.SaveVSchema(ctx, ms.TargetKeyspace, tc.targetVSchema) + err := env.ws.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: tc.targetVSchema, + }) require.NoError(t, err) } @@ -1076,10 +1082,16 @@ func TestCreateLookupVindexFull(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(ctx, ms.TargetKeyspace, &vschemapb.Keyspace{}); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: &vschemapb.Keyspace{}, + }); err != nil { t.Fatal(err) } - if err := env.topoServ.SaveVSchema(ctx, ms.SourceKeyspace, sourceVSchema); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: sourceVSchema, + }); err != nil { t.Fatal(err) } @@ -1133,7 +1145,7 @@ func TestCreateLookupVindexFull(t *testing.T) { } vschema, err := env.topoServ.GetVSchema(ctx, ms.SourceKeyspace) require.NoError(t, err) - utils.MustMatch(t, wantvschema, vschema) + utils.MustMatch(t, wantvschema, vschema.Keyspace) wantvschema = &vschemapb.Keyspace{ Tables: map[string]*vschemapb.Table{ @@ -1142,7 +1154,7 @@ func TestCreateLookupVindexFull(t *testing.T) { } vschema, err = env.topoServ.GetVSchema(ctx, ms.TargetKeyspace) require.NoError(t, err) - utils.MustMatch(t, wantvschema, vschema) + utils.MustMatch(t, wantvschema, vschema.Keyspace) } func TestCreateLookupVindexCreateDDL(t *testing.T) { @@ -1172,7 +1184,10 @@ func TestCreateLookupVindexCreateDDL(t *testing.T) { }, } setStartingVschema := func() { - err := env.topoServ.SaveVSchema(ctx, ms.SourceKeyspace, vs) + err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: vs, + }) require.NoError(t, err) } setStartingVschema() @@ -1209,25 +1224,28 @@ func TestCreateLookupVindexCreateDDL(t *testing.T) { }, preFunc: func() { // The vschema entries will already exist and we will re-use them. - err := env.ws.ts.SaveVSchema(ctx, ms.SourceKeyspace, &vschemapb.Keyspace{ - Vindexes: map[string]*vschemapb.Vindex{ - "v": { - Type: "lookup_unique", - Params: map[string]string{ - "table": fmt.Sprintf("%s.lkp", ms.TargetKeyspace), - "from": "c1", - "to": "c2", - "write_only": "true", // It has not been externalized yet + err := env.ws.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "v": { + Type: "lookup_unique", + Params: map[string]string{ + "table": fmt.Sprintf("%s.lkp", ms.TargetKeyspace), + "from": "c1", + "to": "c2", + "write_only": "true", // It has not been externalized yet + }, + Owner: "t1", }, - Owner: "t1", }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Name: "v", - Column: "col2", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "v", + Column: "col2", + }}, + }, }, }, }) @@ -1270,17 +1288,20 @@ func TestCreateLookupVindexCreateDDL(t *testing.T) { preFunc: func() { // The existing vindex vschema entry differs from what we want to // create so we cannot re-use it. - err := env.ws.ts.SaveVSchema(ctx, ms.SourceKeyspace, &vschemapb.Keyspace{ - Vindexes: map[string]*vschemapb.Vindex{ - "v": { - Type: "lookup_unique", - Params: map[string]string{ - "table": fmt.Sprintf("%s.lkp", ms.TargetKeyspace), - "from": "c1", - "to": "c2", - "write_only": "false", // This vindex has been externalized + err := env.ws.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "v": { + Type: "lookup_unique", + Params: map[string]string{ + "table": fmt.Sprintf("%s.lkp", ms.TargetKeyspace), + "from": "c1", + "to": "c2", + "write_only": "false", // This vindex has been externalized + }, + Owner: "t1", }, - Owner: "t1", }, }, }) @@ -1319,13 +1340,16 @@ func TestCreateLookupVindexCreateDDL(t *testing.T) { preFunc: func() { // The existing ColumnVindexes vschema entry differs from what we // want to create so we cannot re-use it. - err := env.ws.ts.SaveVSchema(ctx, ms.SourceKeyspace, &vschemapb.Keyspace{ - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Name: "v", - Columns: []string{"col1", "col2"}, - }}, + err := env.ws.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "v", + Columns: []string{"col1", "col2"}, + }}, + }, }, }, }) @@ -1515,7 +1539,8 @@ func TestCreateLookupVindexCreateDDL(t *testing.T) { setStartingVschema() }() } - outms, _, _, cancelFunc, err := env.ws.prepareCreateLookup(ctx, "workflow", ms.SourceKeyspace, tcase.specs, false) + lv := newLookupVindex(env.ws) + outms, _, _, cancelFunc, err := lv.prepareCreate(ctx, "workflow", ms.SourceKeyspace, tcase.specs, false) if tcase.err != "" { require.Error(t, err) require.Contains(t, err.Error(), tcase.err, "prepareCreateLookup(%s) err: %v, does not contain %v", tcase.description, err, tcase.err) @@ -1756,14 +1781,21 @@ func TestCreateLookupVindexSourceVSchema(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(ctx, ms.TargetKeyspace, &vschemapb.Keyspace{}); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: &vschemapb.Keyspace{}, + }); err != nil { t.Fatal(err) } - if err := env.topoServ.SaveVSchema(ctx, ms.SourceKeyspace, tcase.sourceVSchema); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: tcase.sourceVSchema, + }); err != nil { t.Fatal(err) } - _, got, _, _, err := env.ws.prepareCreateLookup(ctx, "workflow", ms.SourceKeyspace, specs, false) + lv := newLookupVindex(env.ws) + _, got, _, _, err := lv.prepareCreate(ctx, "workflow", ms.SourceKeyspace, specs, false) require.NoError(t, err) if !proto.Equal(got, tcase.out) { t.Errorf("%s: got:\n%v, want\n%v", tcase.description, got, tcase.out) @@ -1797,7 +1829,10 @@ func TestCreateLookupVindexTargetVSchema(t *testing.T) { }, }, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, sourcevs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: sourcevs, + }); err != nil { t.Fatal(err) } @@ -1984,32 +2019,38 @@ func TestCreateLookupVindexTargetVSchema(t *testing.T) { err: "type SET is not recommended for a vindex", }} for _, tcase := range testcases { - env.tmc.schema[ms.SourceKeyspace+".t1"] = &tabletmanagerdatapb.SchemaDefinition{ - TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ - Fields: []*querypb.Field{{ - Name: "col2", - Type: tcase.sourceFieldType, + t.Run(tcase.description, func(t *testing.T) { + env.tmc.schema[ms.SourceKeyspace+".t1"] = &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Fields: []*querypb.Field{{ + Name: "col2", + Type: tcase.sourceFieldType, + }}, + Schema: sourceSchema, }}, - Schema: sourceSchema, - }}, - } - specs.Vindexes["v"].Params["table"] = fmt.Sprintf("%s.%s", ms.TargetKeyspace, tcase.targetTable) - if err := env.topoServ.SaveVSchema(ctx, ms.TargetKeyspace, tcase.targetVSchema); err != nil { - t.Fatal(err) - } + } + specs.Vindexes["v"].Params["table"] = fmt.Sprintf("%s.%s", ms.TargetKeyspace, tcase.targetTable) + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: tcase.targetVSchema, + }); err != nil { + t.Fatal(err) + } - _, _, got, cancelFunc, err := env.ws.prepareCreateLookup(ctx, "workflow", ms.SourceKeyspace, specs, false) - if tcase.err != "" { - if err == nil || !strings.Contains(err.Error(), tcase.err) { - t.Errorf("prepareCreateLookup(%s) err: %v, must contain %v", tcase.description, err, tcase.err) + lv := newLookupVindex(env.ws) + _, _, got, cancelFunc, err := lv.prepareCreate(ctx, "workflow", ms.SourceKeyspace, specs, false) + if tcase.err != "" { + if err == nil || !strings.Contains(err.Error(), tcase.err) { + t.Errorf("prepareCreateLookup(%s) err: %v, must contain %v", tcase.description, err, tcase.err) + } + return } - continue - } - require.NoError(t, err) - // withTable is a vschema that already contains the table and thus - // we don't make any vschema changes and there's nothing to cancel. - require.True(t, (cancelFunc != nil) == (tcase.targetVSchema != withTable)) - utils.MustMatch(t, tcase.out, got, tcase.description) + require.NoError(t, err) + // withTable is a vschema that already contains the table and thus + // we don't make any vschema changes and there's nothing to cancel. + require.True(t, (cancelFunc != nil) == (tcase.targetVSchema != withTable)) + utils.MustMatch(t, tcase.out, got.Keyspace, tcase.description) + }) } } @@ -2115,11 +2156,15 @@ func TestCreateLookupVindexSameKeyspace(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(ctx, ms.TargetKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } - _, got, _, _, err := env.ws.prepareCreateLookup(ctx, "keyspace", ms.TargetKeyspace, specs, false) + lv := newLookupVindex(env.ws) + _, got, _, _, err := lv.prepareCreate(ctx, "keyspace", ms.TargetKeyspace, specs, false) require.NoError(t, err) if !proto.Equal(got, want) { t.Errorf("same keyspace: got:\n%v, want\n%v", got, want) @@ -2241,11 +2286,15 @@ func TestCreateCustomizedVindex(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(ctx, ms.TargetKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } - _, got, _, _, err := env.ws.prepareCreateLookup(ctx, "workflow", ms.TargetKeyspace, specs, false) + lv := newLookupVindex(env.ws) + _, got, _, _, err := lv.prepareCreate(ctx, "workflow", ms.TargetKeyspace, specs, false) require.NoError(t, err) if !proto.Equal(got, want) { t.Errorf("customize create lookup error same: got:\n%v, want\n%v", got, want) @@ -2359,11 +2408,15 @@ func TestCreateLookupVindexIgnoreNulls(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(ctx, ms.TargetKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } - ms, ks, _, _, err := env.ws.prepareCreateLookup(ctx, "workflow", ms.TargetKeyspace, specs, false) + lv := newLookupVindex(env.ws) + ms, ks, _, _, err := lv.prepareCreate(ctx, "workflow", ms.TargetKeyspace, specs, false) require.NoError(t, err) if !proto.Equal(wantKs, ks) { t.Errorf("unexpected keyspace value: got:\n%v, want\n%v", ks, wantKs) @@ -2439,15 +2492,19 @@ func TestStopAfterCopyFlag(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(ctx, ms.SourceKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } - ms1, _, _, _, err := env.ws.prepareCreateLookup(ctx, "workflow", ms.TargetKeyspace, specs, false) + lv := newLookupVindex(env.ws) + ms1, _, _, _, err := lv.prepareCreate(ctx, "workflow", ms.TargetKeyspace, specs, false) require.NoError(t, err) require.Equal(t, ms1.StopAfterCopy, true) - ms2, _, _, _, err := env.ws.prepareCreateLookup(ctx, "workflow", ms.TargetKeyspace, specs, true) + ms2, _, _, _, err := lv.prepareCreate(ctx, "workflow", ms.TargetKeyspace, specs, true) require.NoError(t, err) require.Equal(t, ms2.StopAfterCopy, false) } @@ -2520,7 +2577,10 @@ func TestCreateLookupVindexFailures(t *testing.T) { }, }, } - err := env.topoServ.SaveVSchema(ctx, ms.TargetKeyspace, vs) + err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: vs, + }) require.NoError(t, err) testcases := []struct { @@ -2588,7 +2648,7 @@ func TestCreateLookupVindexFailures(t *testing.T) { err: "unique vindex 'from' should have only one column", }, { - description: "non-unique lookup should have more than one column", + description: "non-unique lookup can have only one column", input: &vschemapb.Keyspace{ Vindexes: map[string]*vschemapb.Vindex{ "v": { @@ -2601,7 +2661,7 @@ func TestCreateLookupVindexFailures(t *testing.T) { }, }, }, - err: "non-unique vindex 'from' should have more than one column", + err: "", }, { description: "vindex not found", @@ -2859,7 +2919,7 @@ func TestCreateLookupVindexFailures(t *testing.T) { // definition. cvs, err := env.ws.ts.GetVSchema(ctx, ms.TargetKeyspace) require.NoError(t, err) - require.True(t, proto.Equal(vs, cvs), "expected: %+v, got: %+v", vs, cvs) + require.True(t, proto.Equal(vs, cvs.Keyspace), "expected: %+v, got: %+v", vs, cvs) }) } } @@ -3121,7 +3181,10 @@ func TestKeyRangesEqualOptimization(t *testing.T) { defer env.close() // Target is always sharded. - err := env.ws.ts.SaveVSchema(ctx, targetKs, targetVSchema) + err := env.ws.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: targetVSchema, + }) require.NoError(t, err, "SaveVSchema failed: %v", err) for _, tablet := range env.tablets { diff --git a/go/vt/vtctl/workflow/resharder.go b/go/vt/vtctl/workflow/resharder.go index e3f7380af69..c270a9a6f0b 100644 --- a/go/vt/vtctl/workflow/resharder.go +++ b/go/vt/vtctl/workflow/resharder.go @@ -38,7 +38,6 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" - vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) @@ -50,7 +49,7 @@ type resharder struct { sourcePrimaries map[string]*topo.TabletInfo targetShards []*topo.ShardInfo targetPrimaries map[string]*topo.TabletInfo - vschema *vschemapb.Keyspace + vschema *topo.KeyspaceVSchemaInfo refStreams map[string]*refStream // This can be single cell name or cell alias but it can // also be a comma-separated list of cells. diff --git a/go/vt/vtctl/workflow/resharder_test.go b/go/vt/vtctl/workflow/resharder_test.go index 6fe1afb0c70..2840030e7e0 100644 --- a/go/vt/vtctl/workflow/resharder_test.go +++ b/go/vt/vtctl/workflow/resharder_test.go @@ -369,10 +369,13 @@ func TestReadRefStreams(t *testing.T) { }, }, workflow: "wf", - vschema: &vschemapb.Keyspace{ - Tables: map[string]*vschemapb.Table{ - "t1": { - Type: vindexes.TypeReference, + vschema: &topo.KeyspaceVSchemaInfo{ + Name: targetKeyspace.KeyspaceName, + Keyspace: &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "t1": { + Type: vindexes.TypeReference, + }, }, }, }, @@ -485,8 +488,11 @@ func TestBlsIsReference(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { rs := &resharder{ - vschema: &vschemapb.Keyspace{ - Tables: tc.tables, + vschema: &topo.KeyspaceVSchemaInfo{ + Name: "ks", + Keyspace: &vschemapb.Keyspace{ + Tables: tc.tables, + }, }, } diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 6c538a48f75..68eeb31d0d0 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -20,7 +20,6 @@ import ( "context" "errors" "fmt" - "math" "slices" "sort" "strings" @@ -28,28 +27,22 @@ import ( "text/template" "time" - "github.com/google/uuid" - "golang.org/x/exp/maps" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/prototext" - "google.golang.org/protobuf/proto" "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/ptr" - "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/concurrency" - "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/tmutils" - "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" @@ -131,6 +124,8 @@ const ( lockTablesCycles = 2 // Time to wait between LOCK TABLES cycles on the sources during SwitchWrites. lockTablesCycleDelay = time.Duration(100 * time.Millisecond) + + SqlUnfreezeWorkflow = "update _vt.vreplication set state='Running', message='' where db_name=%a and workflow=%a" ) var ( @@ -558,6 +553,43 @@ func (s *Server) getWorkflowState(ctx context.Context, targetKeyspace, workflowN return ts, state, nil } +// LookupVindexComplete checks if the lookup vindex has been externalized, +// and if the vindex has an owner, it deletes the workflow. +func (s *Server) LookupVindexComplete(ctx context.Context, req *vtctldatapb.LookupVindexCompleteRequest) (*vtctldatapb.LookupVindexCompleteResponse, error) { + span, ctx := trace.NewSpan(ctx, "workflow.Server.LookupVindexComplete") + defer span.Finish() + + span.Annotate("keyspace", req.Keyspace) + span.Annotate("name", req.Name) + span.Annotate("table_keyspace", req.TableKeyspace) + + vindex, _, err := getVindexAndVSchema(ctx, s.ts, req.Keyspace, req.Name) + if err != nil { + return nil, err + } + + targetShards, err := s.ts.GetServingShards(ctx, req.TableKeyspace) + if err != nil { + return nil, err + } + + lv := newLookupVindex(s) + if err = lv.validateExternalized(ctx, vindex, req.Name, targetShards); err != nil { + return nil, err + } + + resp := &vtctldatapb.LookupVindexCompleteResponse{} + if _, derr := s.WorkflowDelete(ctx, &vtctldatapb.WorkflowDeleteRequest{ + Keyspace: req.TableKeyspace, + Workflow: req.Name, + KeepData: true, + KeepRoutingRules: true, + }); derr != nil { + return nil, vterrors.Wrapf(derr, "failed to delete workflow %s", req.Name) + } + return resp, nil +} + // LookupVindexCreate creates the lookup vindex in the specified // keyspace and creates a VReplication workflow to backfill that // vindex from the keyspace to the target/lookup table specified. @@ -571,12 +603,14 @@ func (s *Server) LookupVindexCreate(ctx context.Context, req *vtctldatapb.Lookup span.Annotate("cells", req.Cells) span.Annotate("tablet_types", req.TabletTypes) - ms, sourceVSchema, targetVSchema, cancelFunc, err := s.prepareCreateLookup(ctx, req.Workflow, req.Keyspace, req.Vindex, req.ContinueAfterCopyWithOwner) + lv := newLookupVindex(s) + + ms, sourceVSchema, targetVSchema, cancelFunc, err := lv.prepareCreate(ctx, req.Workflow, req.Keyspace, req.Vindex, req.ContinueAfterCopyWithOwner) if err != nil { return nil, err } - if err := s.ts.SaveVSchema(ctx, ms.TargetKeyspace, targetVSchema); err != nil { + if err := s.ts.SaveVSchema(ctx, targetVSchema); err != nil { return nil, vterrors.Wrapf(err, "failed to save updated vschema '%v' in the %s keyspace", targetVSchema, ms.TargetKeyspace) } @@ -592,7 +626,7 @@ func (s *Server) LookupVindexCreate(ctx context.Context, req *vtctldatapb.Lookup return nil, err } if ms.SourceKeyspace != ms.TargetKeyspace { - if err := s.ts.SaveVSchema(ctx, ms.SourceKeyspace, sourceVSchema); err != nil { + if err := s.ts.SaveVSchema(ctx, sourceVSchema); err != nil { return nil, vterrors.Wrapf(err, "failed to save updated vschema '%v' in the %s keyspace", sourceVSchema, ms.SourceKeyspace) } @@ -607,7 +641,7 @@ func (s *Server) LookupVindexCreate(ctx context.Context, req *vtctldatapb.Lookup // LookupVindexExternalize externalizes a lookup vindex that's // finished backfilling or has caught up. If the vindex has an -// owner then the workflow will also be deleted. +// owner then the workflow will also be stopped. func (s *Server) LookupVindexExternalize(ctx context.Context, req *vtctldatapb.LookupVindexExternalizeRequest) (*vtctldatapb.LookupVindexExternalizeResponse, error) { span, ctx := trace.NewSpan(ctx, "workflow.Server.LookupVindexExternalize") defer span.Finish() @@ -615,15 +649,11 @@ func (s *Server) LookupVindexExternalize(ctx context.Context, req *vtctldatapb.L span.Annotate("keyspace", req.Keyspace) span.Annotate("name", req.Name) span.Annotate("table_keyspace", req.TableKeyspace) + span.Annotate("delete_workflow", req.DeleteWorkflow) - // Find the lookup vindex by by name. - sourceVschema, err := s.ts.GetVSchema(ctx, req.Keyspace) + vindex, sourceKsVS, err := getVindexAndVSchema(ctx, s.ts, req.Keyspace, req.Name) if err != nil { - return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get vschema for the %s keyspace", req.Keyspace) - } - vindex := sourceVschema.Vindexes[req.Name] - if vindex == nil { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "vindex %s not found in the %s keyspace", req.Name, req.Keyspace) + return nil, err } targetShards, err := s.ts.GetServingShards(ctx, req.TableKeyspace) @@ -642,8 +672,8 @@ func (s *Server) LookupVindexExternalize(ctx context.Context, req *vtctldatapb.L if err != nil { return err } - if res == nil { - return vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "workflow %s not found on %v", req.Name, targetPrimary.Alias) + if res == nil || res.Workflow == "" { + return vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "workflow %s not found on %v", req.Name, topoproto.TabletAliasString(targetPrimary.Alias)) } for _, stream := range res.Streams { if stream.Bls.Filter == nil || len(stream.Bls.Filter.Rules) != 1 { @@ -671,28 +701,105 @@ func (s *Server) LookupVindexExternalize(ctx context.Context, req *vtctldatapb.L resp := &vtctldatapb.LookupVindexExternalizeResponse{} if vindex.Owner != "" { - // If there is an owner, we have to delete the streams. Once we externalize it - // the VTGate will now be responsible for keeping the lookup table up to date - // with the owner table. - if _, derr := s.WorkflowDelete(ctx, &vtctldatapb.WorkflowDeleteRequest{ - Keyspace: req.TableKeyspace, - Workflow: req.Name, - KeepData: true, // Not relevant - KeepRoutingRules: true, // Not relevant - }); derr != nil { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "failed to delete workflow %s: %v", req.Name, derr) + // If there is an owner, we have to stop/delete the streams. Once we + // externalize it the VTGate will now be responsible for keeping the + // lookup table up to date with the owner table. + if req.DeleteWorkflow { + // Delete the workflow. + if _, derr := s.WorkflowDelete(ctx, &vtctldatapb.WorkflowDeleteRequest{ + Keyspace: req.TableKeyspace, + Workflow: req.Name, + KeepData: true, // Not relevant + KeepRoutingRules: true, // Not relevant + }); derr != nil { + return nil, vterrors.Wrapf(derr, "failed to delete workflow %s", req.Name) + } + resp.WorkflowDeleted = true + } else { + // Freeze the workflow. + err = forAllShards(targetShards, func(si *topo.ShardInfo) error { + tabletInfo, err := s.ts.GetTablet(ctx, si.PrimaryAlias) + if err != nil { + return err + } + _, err = s.tmc.UpdateVReplicationWorkflow(ctx, tabletInfo.Tablet, &tabletmanagerdatapb.UpdateVReplicationWorkflowRequest{ + Workflow: req.Name, + State: ptr.Of(binlogdatapb.VReplicationWorkflowState_Stopped), + Message: ptr.Of(Frozen), + }) + if err != nil { + return vterrors.Wrapf(err, "failed to stop workflow %s on shard %s/%s", req.Name, tabletInfo.Keyspace, tabletInfo.Shard) + } + return nil + }) + if err != nil { + return nil, err + } + resp.WorkflowStopped = true } - resp.WorkflowDeleted = true } // Remove the write_only param and save the source vschema. delete(vindex.Params, "write_only") - if err := s.ts.SaveVSchema(ctx, req.Keyspace, sourceVschema); err != nil { + if err := s.ts.SaveVSchema(ctx, sourceKsVS); err != nil { return nil, err } return resp, s.ts.RebuildSrvVSchema(ctx, nil) } +// LookupVindexInternalize internalizes a lookup vindex. +func (s *Server) LookupVindexInternalize(ctx context.Context, req *vtctldatapb.LookupVindexInternalizeRequest) (*vtctldatapb.LookupVindexInternalizeResponse, error) { + span, ctx := trace.NewSpan(ctx, "workflow.Server.LookupVindexInternalize") + defer span.Finish() + + span.Annotate("keyspace", req.Keyspace) + span.Annotate("name", req.Name) + span.Annotate("table_keyspace", req.TableKeyspace) + + vindex, sourceKsVS, err := getVindexAndVSchema(ctx, s.ts, req.Keyspace, req.Name) + if err != nil { + return nil, err + } + + targetShards, err := s.ts.GetServingShards(ctx, req.TableKeyspace) + if err != nil { + return nil, err + } + + lv := newLookupVindex(s) + if err = lv.validateExternalized(ctx, vindex, req.Name, targetShards); err != nil { + return nil, err + } + + // Make the vindex back to write_only and save the source vschema. + vindex.Params["write_only"] = "true" + if err := s.ts.SaveVSchema(ctx, sourceKsVS); err != nil { + return nil, err + } + + resp := &vtctldatapb.LookupVindexInternalizeResponse{} + err = forAllShards(targetShards, func(si *topo.ShardInfo) error { + tabletInfo, err := s.ts.GetTablet(ctx, si.PrimaryAlias) + if err != nil { + return err + } + query, err := sqlparser.ParseAndBind(SqlUnfreezeWorkflow, + sqltypes.StringBindVariable(tabletInfo.DbName()), + sqltypes.StringBindVariable(req.Name), + ) + if err != nil { + return err + } + _, err = s.tmc.VReplicationExec(ctx, tabletInfo.Tablet, query) + return err + }) + if err != nil { + return nil, err + } + + return resp, s.ts.RebuildSrvVSchema(ctx, nil) +} + // Materialize performs the steps needed to materialize a list of // tables based on the materialization specs. func (s *Server) Materialize(ctx context.Context, ms *vtctldatapb.MaterializeSettings) error { @@ -715,11 +822,8 @@ func (s *Server) Materialize(ctx context.Context, ms *vtctldatapb.MaterializeSet cells[i] = strings.TrimSpace(cells[i]) } - switch { - case len(ms.ReferenceTables) == 0 && len(ms.TableSettings) == 0: - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "either --table-settings or --reference-tables must be specified") - case len(ms.ReferenceTables) > 0 && len(ms.TableSettings) > 0: - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot specify both --table-settings and --reference-tables") + if err := validateMaterializeSettings(ms); err != nil { + return err } for _, table := range ms.ReferenceTables { @@ -746,6 +850,17 @@ func (s *Server) Materialize(ctx context.Context, ms *vtctldatapb.MaterializeSet return mz.startStreams(ctx) } +func validateMaterializeSettings(ms *vtctldatapb.MaterializeSettings) error { + switch { + case len(ms.ReferenceTables) == 0 && len(ms.TableSettings) == 0: + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "either --table-settings or --reference-tables must be specified") + case len(ms.ReferenceTables) > 0 && len(ms.TableSettings) > 0: + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot specify both --table-settings and --reference-tables") + } + + return nil +} + // MoveTablesCreate is part of the vtctlservicepb.VtctldServer interface. // It passes the embedded TabletRequest object to the given keyspace's // target primary tablets that will be executing the workflow. @@ -800,9 +915,10 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl s.Logger().Infof("Successfully opened external topo: %+v", externalTopo) } - var vschema *vschemapb.Keyspace - var origVSchema *vschemapb.Keyspace // If we need to rollback a failed create - vschema, err = s.ts.GetVSchema(ctx, targetKeyspace) + origVSchema := &topo.KeyspaceVSchemaInfo{ // If we need to rollback a failed create + Name: targetKeyspace, + } + vschema, err := s.ts.GetVSchema(ctx, targetKeyspace) if err != nil { return nil, err } @@ -827,7 +943,7 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl return nil, err } if len(tables) > 0 { - err = validateSourceTablesExist(ctx, sourceKeyspace, ksTables, tables) + err = validateSourceTablesExist(sourceKeyspace, ksTables, tables) if err != nil { return nil, err } @@ -839,7 +955,7 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl } } if len(req.ExcludeTables) > 0 { - err = validateSourceTablesExist(ctx, sourceKeyspace, ksTables, req.ExcludeTables) + err = validateSourceTablesExist(sourceKeyspace, ksTables, req.ExcludeTables) if err != nil { return nil, err } @@ -858,12 +974,14 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl if !vschema.Sharded { // Save the original in case we need to restore it for a late failure in - // the defer(). - origVSchema = vschema.CloneVT() - if err := s.addTablesToVSchema(ctx, sourceKeyspace, vschema, tables, externalTopo == nil); err != nil { + // the defer(). We do NOT want to clone the version field as we will + // intentionally be going back in time. So we only clone the internal + // vschemapb.Keyspace field. + origVSchema.Keyspace = vschema.Keyspace.CloneVT() + if err := s.addTablesToVSchema(ctx, sourceKeyspace, vschema.Keyspace, tables, externalTopo == nil); err != nil { return nil, err } - if err := s.ts.SaveVSchema(ctx, targetKeyspace, vschema); err != nil { + if err := s.ts.SaveVSchema(ctx, vschema); err != nil { return nil, err } } @@ -964,7 +1082,7 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl if origVSchema == nil { // There's no previous version to restore return } - if cerr := s.ts.SaveVSchema(ctx, targetKeyspace, origVSchema); cerr != nil { + if cerr := s.ts.SaveVSchema(ctx, origVSchema); cerr != nil { err = vterrors.Wrapf(err, "failed to restore original target vschema: %v", cerr) } } @@ -1243,287 +1361,6 @@ func (s *Server) ReshardCreate(ctx context.Context, req *vtctldatapb.ReshardCrea }) } -// VDiffCreate is part of the vtctlservicepb.VtctldServer interface. -// It passes on the request to the target primary tablets that are -// participating in the given workflow and VDiff. -func (s *Server) VDiffCreate(ctx context.Context, req *vtctldatapb.VDiffCreateRequest) (*vtctldatapb.VDiffCreateResponse, error) { - span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffCreate") - defer span.Finish() - - span.Annotate("keyspace", req.TargetKeyspace) - span.Annotate("workflow", req.Workflow) - span.Annotate("uuid", req.Uuid) - span.Annotate("source_cells", req.SourceCells) - span.Annotate("target_cells", req.TargetCells) - span.Annotate("tablet_types", req.TabletTypes) - span.Annotate("tables", req.Tables) - span.Annotate("auto_retry", req.AutoRetry) - span.Annotate("max_diff_duration", req.MaxDiffDuration) - if req.AutoStart != nil { - span.Annotate("auto_start", req.GetAutoStart()) - } - - var err error - req.Uuid = strings.TrimSpace(req.Uuid) - if req.Uuid == "" { // Generate a UUID - req.Uuid = uuid.New().String() - } else { // Validate UUID if provided - if err = uuid.Validate(req.Uuid); err != nil { - return nil, vterrors.Wrapf(err, "invalid UUID provided: %s", req.Uuid) - } - } - - tabletTypesStr := discovery.BuildTabletTypesString(req.TabletTypes, req.TabletSelectionPreference) - - if req.Limit == 0 { // This would produce no useful results - req.Limit = math.MaxInt64 - } - // This is a pointer so there's no ZeroValue in the message - // and an older v18 client will not provide it. - if req.MaxDiffDuration == nil { - req.MaxDiffDuration = &vttimepb.Duration{} - } - // The other vttime.Duration vars should not be nil as the - // client should always provide them, but we check anyway to - // be safe. - if req.FilteredReplicationWaitTime == nil { - // A value of 0 is not valid as the vdiff will never succeed. - req.FilteredReplicationWaitTime = &vttimepb.Duration{ - Seconds: int64(DefaultTimeout.Seconds()), - } - } - if req.WaitUpdateInterval == nil { - req.WaitUpdateInterval = &vttimepb.Duration{} - } - - autoStart := true - if req.AutoStart != nil { - autoStart = req.GetAutoStart() - } - - options := &tabletmanagerdatapb.VDiffOptions{ - PickerOptions: &tabletmanagerdatapb.VDiffPickerOptions{ - TabletTypes: tabletTypesStr, - SourceCell: strings.Join(req.SourceCells, ","), - TargetCell: strings.Join(req.TargetCells, ","), - }, - CoreOptions: &tabletmanagerdatapb.VDiffCoreOptions{ - Tables: strings.Join(req.Tables, ","), - AutoRetry: req.AutoRetry, - MaxRows: req.Limit, - TimeoutSeconds: req.FilteredReplicationWaitTime.Seconds, - MaxExtraRowsToCompare: req.MaxExtraRowsToCompare, - UpdateTableStats: req.UpdateTableStats, - MaxDiffSeconds: req.MaxDiffDuration.Seconds, - AutoStart: &autoStart, - }, - ReportOptions: &tabletmanagerdatapb.VDiffReportOptions{ - OnlyPks: req.OnlyPKs, - DebugQuery: req.DebugQuery, - MaxSampleRows: req.MaxReportSampleRows, - RowDiffColumnTruncateAt: req.RowDiffColumnTruncateAt, - }, - } - - tabletreq := &tabletmanagerdatapb.VDiffRequest{ - Keyspace: req.TargetKeyspace, - Workflow: req.Workflow, - Action: string(vdiff.CreateAction), - Options: options, - VdiffUuid: req.Uuid, - } - - ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) - if err != nil { - return nil, err - } - if ts.frozen { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "invalid VDiff run: writes have been already been switched for workflow %s.%s", - req.TargetKeyspace, req.Workflow) - } - - workflowStatus, err := s.getWorkflowStatus(ctx, req.TargetKeyspace, req.Workflow) - if err != nil { - return nil, err - } - if workflowStatus != binlogdatapb.VReplicationWorkflowState_Running { - s.Logger().Infof("Workflow %s.%s is not running, cannot start VDiff in state %s", req.TargetKeyspace, req.Workflow, workflowStatus) - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, - "not all streams are running in workflow %s.%s", req.TargetKeyspace, req.Workflow) - } - - err = ts.ForAllTargets(func(target *MigrationTarget) error { - _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) - return err - }) - if err != nil { - s.Logger().Errorf("Error executing vdiff create action: %v", err) - return nil, err - } - - return &vtctldatapb.VDiffCreateResponse{ - UUID: req.Uuid, - }, nil -} - -// VDiffDelete is part of the vtctlservicepb.VtctldServer interface. -func (s *Server) VDiffDelete(ctx context.Context, req *vtctldatapb.VDiffDeleteRequest) (*vtctldatapb.VDiffDeleteResponse, error) { - span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffDelete") - defer span.Finish() - - span.Annotate("keyspace", req.TargetKeyspace) - span.Annotate("workflow", req.Workflow) - span.Annotate("argument", req.Arg) - - tabletreq := &tabletmanagerdatapb.VDiffRequest{ - Keyspace: req.TargetKeyspace, - Workflow: req.Workflow, - Action: string(vdiff.DeleteAction), - ActionArg: req.Arg, - } - - ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) - if err != nil { - return nil, err - } - - err = ts.ForAllTargets(func(target *MigrationTarget) error { - _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) - return err - }) - if err != nil { - s.Logger().Errorf("Error executing vdiff delete action: %v", err) - return nil, err - } - - return &vtctldatapb.VDiffDeleteResponse{}, nil -} - -// VDiffResume is part of the vtctlservicepb.VtctldServer interface. -func (s *Server) VDiffResume(ctx context.Context, req *vtctldatapb.VDiffResumeRequest) (*vtctldatapb.VDiffResumeResponse, error) { - span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffResume") - defer span.Finish() - - targetShards := req.GetTargetShards() - - span.Annotate("keyspace", req.TargetKeyspace) - span.Annotate("workflow", req.Workflow) - span.Annotate("uuid", req.Uuid) - span.Annotate("target_shards", targetShards) - - tabletreq := &tabletmanagerdatapb.VDiffRequest{ - Keyspace: req.TargetKeyspace, - Workflow: req.Workflow, - Action: string(vdiff.ResumeAction), - VdiffUuid: req.Uuid, - } - - ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) - if err != nil { - return nil, err - } - - if len(targetShards) > 0 { - if err := applyTargetShards(ts, targetShards); err != nil { - return nil, err - } - } - - err = ts.ForAllTargets(func(target *MigrationTarget) error { - _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) - return err - }) - if err != nil { - s.Logger().Errorf("Error executing vdiff resume action: %v", err) - return nil, err - } - - return &vtctldatapb.VDiffResumeResponse{}, nil -} - -// VDiffShow is part of the vtctlservicepb.VtctldServer interface. -func (s *Server) VDiffShow(ctx context.Context, req *vtctldatapb.VDiffShowRequest) (*vtctldatapb.VDiffShowResponse, error) { - span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffShow") - defer span.Finish() - - span.Annotate("keyspace", req.TargetKeyspace) - span.Annotate("workflow", req.Workflow) - span.Annotate("argument", req.Arg) - - tabletreq := &tabletmanagerdatapb.VDiffRequest{ - Keyspace: req.TargetKeyspace, - Workflow: req.Workflow, - Action: string(vdiff.ShowAction), - ActionArg: req.Arg, - } - - ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) - if err != nil { - return nil, err - } - - output := &vdiffOutput{ - responses: make(map[string]*tabletmanagerdatapb.VDiffResponse, len(ts.targets)), - err: nil, - } - output.err = ts.ForAllTargets(func(target *MigrationTarget) error { - resp, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) - output.mu.Lock() - defer output.mu.Unlock() - output.responses[target.GetShard().ShardName()] = resp - return err - }) - if output.err != nil { - s.Logger().Errorf("Error executing vdiff show action: %v", output.err) - return nil, output.err - } - return &vtctldatapb.VDiffShowResponse{ - TabletResponses: output.responses, - }, nil -} - -// VDiffStop is part of the vtctlservicepb.VtctldServer interface. -func (s *Server) VDiffStop(ctx context.Context, req *vtctldatapb.VDiffStopRequest) (*vtctldatapb.VDiffStopResponse, error) { - span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffStop") - defer span.Finish() - - targetShards := req.GetTargetShards() - - span.Annotate("keyspace", req.TargetKeyspace) - span.Annotate("workflow", req.Workflow) - span.Annotate("uuid", req.Uuid) - span.Annotate("target_shards", targetShards) - - tabletreq := &tabletmanagerdatapb.VDiffRequest{ - Keyspace: req.TargetKeyspace, - Workflow: req.Workflow, - Action: string(vdiff.StopAction), - VdiffUuid: req.Uuid, - } - - ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) - if err != nil { - return nil, err - } - - if len(targetShards) > 0 { - if err := applyTargetShards(ts, targetShards); err != nil { - return nil, err - } - } - - err = ts.ForAllTargets(func(target *MigrationTarget) error { - _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) - return err - }) - if err != nil { - s.Logger().Errorf("Error executing vdiff stop action: %v", err) - return nil, err - } - - return &vtctldatapb.VDiffStopResponse{}, nil -} - // WorkflowDelete is part of the vtctlservicepb.VtctldServer interface. // It passes on the request to the target primary tablets that are // participating in the given workflow. @@ -1885,8 +1722,10 @@ func (s *Server) WorkflowUpdate(ctx context.Context, req *vtctldatapb.WorkflowUp span.Annotate("on_ddl", req.TabletRequest.OnDdl) span.Annotate("state", req.TabletRequest.State) span.Annotate("config_overrides", req.TabletRequest.ConfigOverrides) + span.Annotate("shards", req.TabletRequest.Shards) vx := vexec.NewVExec(req.Keyspace, req.TabletRequest.Workflow, s.ts, s.tmc, s.env.Parser()) + vx.SetShardSubset(req.TabletRequest.Shards) callback := func(ctx context.Context, tablet *topo.TabletInfo) (*querypb.QueryResult, error) { res, err := s.tmc.UpdateVReplicationWorkflow(ctx, tablet.Tablet, req.TabletRequest) if err != nil { @@ -2310,7 +2149,7 @@ func (s *Server) buildTrafficSwitcher(ctx context.Context, targetKeyspace, workf if err != nil { return nil, err } - ts.sourceKSSchema, err = vindexes.BuildKeyspaceSchema(vs, ts.sourceKeyspace, s.env.Parser()) + ts.sourceKSSchema, err = vindexes.BuildKeyspaceSchema(vs.Keyspace, ts.sourceKeyspace, s.env.Parser()) if err != nil { return nil, err } @@ -3297,7 +3136,7 @@ func (s *Server) VReplicationExec(ctx context.Context, tabletAlias *topodatapb.T } // CopySchemaShard copies the schema from a source tablet to the -// specified shard. The schema is applied directly on the primary of +// specified shard. The schema is applied directly on the primary of // the destination shard, and is propagated to the replicas through // binlogs. func (s *Server) CopySchemaShard(ctx context.Context, sourceTabletAlias *topodatapb.TabletAlias, tables, excludeTables []string, includeViews bool, destKeyspace, destShard string, waitReplicasTimeout time.Duration, skipVerify bool) error { @@ -3408,417 +3247,6 @@ func fillStringTemplate(tmpl string, vars any) (string, error) { return data.String(), nil } -// prepareCreateLookup performs the preparatory steps for creating a -// Lookup Vindex. -func (s *Server) prepareCreateLookup(ctx context.Context, workflow, keyspace string, specs *vschemapb.Keyspace, continueAfterCopyWithOwner bool) ( - ms *vtctldatapb.MaterializeSettings, sourceVSchema, targetVSchema *vschemapb.Keyspace, cancelFunc func() error, err error) { - // Important variables are pulled out here. - var ( - vindexName string - vindex *vschemapb.Vindex - targetKeyspace string - targetTableName string - vindexFromCols []string - vindexToCol string - vindexIgnoreNulls bool - - sourceTableName string - // sourceTable is the supplied table info. - sourceTable *vschemapb.Table - // sourceVSchemaTable is the table info present in the vschema. - sourceVSchemaTable *vschemapb.Table - // sourceVindexColumns are computed from the input sourceTable. - sourceVindexColumns []string - - // Target table info. - createDDL string - materializeQuery string - ) - - // Validate input vindex. - if specs == nil { - return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "no vindex provided") - } - if len(specs.Vindexes) != 1 { - return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "only one vindex must be specified") - } - vindexName = maps.Keys(specs.Vindexes)[0] - vindex = maps.Values(specs.Vindexes)[0] - if !strings.Contains(vindex.Type, "lookup") { - return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "vindex %s is not a lookup type", vindex.Type) - } - targetKeyspace, targetTableName, err = s.env.Parser().ParseTable(vindex.Params["table"]) - if err != nil || targetKeyspace == "" { - return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "vindex table name (%s) must be in the form .
", vindex.Params["table"]) - } - vindexFromCols = strings.Split(vindex.Params["from"], ",") - for i, col := range vindexFromCols { - vindexFromCols[i] = strings.TrimSpace(col) - } - if strings.Contains(vindex.Type, "unique") { - if len(vindexFromCols) != 1 { - return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unique vindex 'from' should have only one column") - } - } else { - if len(vindexFromCols) < 2 { - return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "non-unique vindex 'from' should have more than one column") - } - } - vindexToCol = vindex.Params["to"] - // Make the vindex write_only. If one exists already in the vschema, - // it will need to match this vindex exactly, including the write_only setting. - vindex.Params["write_only"] = "true" - // See if we can create the vindex without errors. - if _, err := vindexes.CreateVindex(vindex.Type, vindexName, vindex.Params); err != nil { - return nil, nil, nil, nil, err - } - if ignoreNullsStr, ok := vindex.Params["ignore_nulls"]; ok { - // This mirrors the behavior of vindexes.boolFromMap(). - switch ignoreNullsStr { - case "true": - vindexIgnoreNulls = true - case "false": - vindexIgnoreNulls = false - default: - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "ignore_nulls (%s) value must be 'true' or 'false'", - ignoreNullsStr) - } - } - - // Validate input table. - if len(specs.Tables) < 1 || len(specs.Tables) > 2 { - return nil, nil, nil, nil, fmt.Errorf("one or two tables must be specified") - } - // Loop executes once or twice. - for tableName, table := range specs.Tables { - if len(table.ColumnVindexes) != 1 { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "exactly one ColumnVindex must be specified for the %s table", - tableName) - } - if tableName != targetTableName { // This is the source table. - sourceTableName = tableName - sourceTable = table - continue - } - // This is a primary vindex definition for the target table - // which allows you to override the vindex type used. - var vindexCols []string - if len(table.ColumnVindexes[0].Columns) != 0 { - vindexCols = table.ColumnVindexes[0].Columns - } else { - if table.ColumnVindexes[0].Column == "" { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "at least one column must be specified in ColumnVindexes for the %s table", - tableName) - } - vindexCols = []string{table.ColumnVindexes[0].Column} - } - if !slices.Equal(vindexCols, vindexFromCols) { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "columns in the lookup table %s primary vindex (%s) don't match the 'from' columns specified (%s)", - tableName, strings.Join(vindexCols, ","), strings.Join(vindexFromCols, ",")) - } - } - - // Validate input table and vindex consistency. - if sourceTable == nil || len(sourceTable.ColumnVindexes) != 1 { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "No ColumnVindex found for the owner table (%s) in the %s keyspace", - sourceTable, keyspace) - } - if sourceTable.ColumnVindexes[0].Name != vindexName { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "ColumnVindex name (%s) must match vindex name (%s)", - sourceTable.ColumnVindexes[0].Name, vindexName) - } - if vindex.Owner != "" && vindex.Owner != sourceTableName { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "vindex owner (%s) must match table name (%s)", - vindex.Owner, sourceTableName) - } - if len(sourceTable.ColumnVindexes[0].Columns) != 0 { - sourceVindexColumns = sourceTable.ColumnVindexes[0].Columns - } else { - if sourceTable.ColumnVindexes[0].Column == "" { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "at least one column must be specified in ColumnVindexes for the %s table", - sourceTableName) - } - sourceVindexColumns = []string{sourceTable.ColumnVindexes[0].Column} - } - if len(sourceVindexColumns) != len(vindexFromCols) { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "length of table columns (%d) differs from length of vindex columns (%d)", - len(sourceVindexColumns), len(vindexFromCols)) - } - - // Validate against source vschema. - sourceVSchema, err = s.ts.GetVSchema(ctx, keyspace) - if err != nil { - return nil, nil, nil, nil, err - } - if sourceVSchema.Vindexes == nil { - sourceVSchema.Vindexes = make(map[string]*vschemapb.Vindex) - } - // If source and target keyspaces are the same, make vschemas point - // to the same object. - if keyspace == targetKeyspace { - targetVSchema = sourceVSchema - } else { - targetVSchema, err = s.ts.GetVSchema(ctx, targetKeyspace) - if err != nil { - return nil, nil, nil, nil, err - } - } - if targetVSchema.Vindexes == nil { - targetVSchema.Vindexes = make(map[string]*vschemapb.Vindex) - } - if targetVSchema.Tables == nil { - targetVSchema.Tables = make(map[string]*vschemapb.Table) - } - if existing, ok := sourceVSchema.Vindexes[vindexName]; ok { - if !proto.Equal(existing, vindex) { // If the exact same vindex already exists then we can re-use it - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INTERNAL, "a conflicting vindex named %s already exists in the %s keyspace", - vindexName, keyspace) - } - } - sourceVSchemaTable = sourceVSchema.Tables[sourceTableName] - if sourceVSchemaTable == nil && !schema.IsInternalOperationTableName(sourceTableName) { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INTERNAL, "table %s not found in the %s keyspace", sourceTableName, keyspace) - } - for _, colVindex := range sourceVSchemaTable.ColumnVindexes { - // For a conflict, the vindex name and column should match. - if colVindex.Name != vindexName { - continue - } - var colNames []string - if len(colVindex.Columns) == 0 { - colNames = []string{colVindex.Column} - } else { - colNames = colVindex.Columns - } - // If this is the exact same definition then we can use the existing one. If they - // are not the same then they are two distinct conflicting vindexes and we should - // not proceed. - if !slices.Equal(colNames, sourceVindexColumns) { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "a conflicting ColumnVindex on column(s) %s in table %s already exists in the %s keyspace", - strings.Join(colNames, ","), sourceTableName, keyspace) - } - } - - // Validate against source schema. - sourceShards, err := s.ts.GetServingShards(ctx, keyspace) - if err != nil { - return nil, nil, nil, nil, err - } - onesource := sourceShards[0] - if onesource.PrimaryAlias == nil { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INTERNAL, "source shard %s has no primary", onesource.ShardName()) - } - req := &tabletmanagerdatapb.GetSchemaRequest{Tables: []string{sourceTableName}} - tableSchema, err := schematools.GetSchema(ctx, s.ts, s.tmc, onesource.PrimaryAlias, req) - if err != nil { - return nil, nil, nil, nil, err - } - if len(tableSchema.TableDefinitions) != 1 { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected number of tables (%d) returned from %s schema", - len(tableSchema.TableDefinitions), keyspace) - } - - // Generate "create table" statement. - lines := strings.Split(tableSchema.TableDefinitions[0].Schema, "\n") - if len(lines) < 3 { - // Should never happen. - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INTERNAL, "schema looks incorrect: %s, expecting at least four lines", - tableSchema.TableDefinitions[0].Schema) - } - var modified []string - modified = append(modified, strings.Replace(lines[0], sourceTableName, targetTableName, 1)) - for i := range sourceVindexColumns { - line, err := generateColDef(lines, sourceVindexColumns[i], vindexFromCols[i]) - if err != nil { - return nil, nil, nil, nil, err - } - modified = append(modified, line) - } - - if vindex.Params["data_type"] == "" || strings.EqualFold(vindex.Type, "consistent_lookup_unique") || strings.EqualFold(vindex.Type, "consistent_lookup") { - modified = append(modified, fmt.Sprintf(" %s varbinary(128),", sqlescape.EscapeID(vindexToCol))) - } else { - modified = append(modified, fmt.Sprintf(" %s %s,", sqlescape.EscapeID(vindexToCol), sqlescape.EscapeID(vindex.Params["data_type"]))) - } - buf := sqlparser.NewTrackedBuffer(nil) - fmt.Fprintf(buf, " PRIMARY KEY (") - prefix := "" - for _, col := range vindexFromCols { - fmt.Fprintf(buf, "%s%s", prefix, sqlescape.EscapeID(col)) - prefix = ", " - } - fmt.Fprintf(buf, ")") - modified = append(modified, buf.String()) - modified = append(modified, ")") - createDDL = strings.Join(modified, "\n") - // Confirm that our DDL is valid before we create anything. - if _, err = s.env.Parser().ParseStrictDDL(createDDL); err != nil { - return nil, nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "error: %v; invalid lookup table definition generated: %s", - err, createDDL) - } - - // Generate vreplication query. - buf = sqlparser.NewTrackedBuffer(nil) - buf.Myprintf("select ") - for i := range vindexFromCols { - buf.Myprintf("%s as %s, ", sqlparser.String(sqlparser.NewIdentifierCI(sourceVindexColumns[i])), sqlparser.String(sqlparser.NewIdentifierCI(vindexFromCols[i]))) - } - if strings.EqualFold(vindexToCol, "keyspace_id") || strings.EqualFold(vindex.Type, "consistent_lookup_unique") || strings.EqualFold(vindex.Type, "consistent_lookup") { - buf.Myprintf("keyspace_id() as %s ", sqlparser.String(sqlparser.NewIdentifierCI(vindexToCol))) - } else { - buf.Myprintf("%s as %s ", sqlparser.String(sqlparser.NewIdentifierCI(vindexToCol)), sqlparser.String(sqlparser.NewIdentifierCI(vindexToCol))) - } - buf.Myprintf("from %s", sqlparser.String(sqlparser.NewIdentifierCS(sourceTableName))) - if vindexIgnoreNulls { - buf.Myprintf(" where ") - lastValIdx := len(vindexFromCols) - 1 - for i := range vindexFromCols { - buf.Myprintf("%s is not null", sqlparser.String(sqlparser.NewIdentifierCI(vindexFromCols[i]))) - if i != lastValIdx { - buf.Myprintf(" and ") - } - } - } - if vindex.Owner != "" { - // Only backfill. - buf.Myprintf(" group by ") - for i := range vindexFromCols { - buf.Myprintf("%s, ", sqlparser.String(sqlparser.NewIdentifierCI(vindexFromCols[i]))) - } - buf.Myprintf("%s", sqlparser.String(sqlparser.NewIdentifierCI(vindexToCol))) - } - materializeQuery = buf.String() - - // Save a copy of the original vschema if we modify it and need to provide - // a cancelFunc. - ogTargetVSchema := targetVSchema.CloneVT() - targetChanged := false - - // Update targetVSchema. - targetTable := specs.Tables[targetTableName] - if targetVSchema.Sharded { - // Choose a primary vindex type for the lookup table based on the source - // definition if one was not explicitly specified. - var targetVindexType string - var targetVindex *vschemapb.Vindex - for _, field := range tableSchema.TableDefinitions[0].Fields { - if sourceVindexColumns[0] == field.Name { - if targetTable != nil && len(targetTable.ColumnVindexes) > 0 { - targetVindexType = targetTable.ColumnVindexes[0].Name - } - if targetVindexType == "" { - targetVindexType, err = vindexes.ChooseVindexForType(field.Type) - if err != nil { - return nil, nil, nil, nil, err - } - } - targetVindex = &vschemapb.Vindex{ - Type: targetVindexType, - } - break - } - } - if targetVindex == nil { - // Unreachable. We validated column names when generating the DDL. - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INTERNAL, "column %s not found in target schema %s", - sourceVindexColumns[0], tableSchema.TableDefinitions[0].Schema) - } - if existing, ok := targetVSchema.Vindexes[targetVindexType]; ok { - if !proto.Equal(existing, targetVindex) { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "a conflicting vindex named %v already exists in the %s keyspace", - targetVindexType, targetKeyspace) - } - } else { - targetVSchema.Vindexes[targetVindexType] = targetVindex - targetChanged = true - } - - targetTable = &vschemapb.Table{ - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: vindexFromCols[0], - Name: targetVindexType, - }}, - } - } else { - targetTable = &vschemapb.Table{} - } - if existing, ok := targetVSchema.Tables[targetTableName]; ok { - if !proto.Equal(existing, targetTable) { - return nil, nil, nil, nil, - vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "a conflicting table named %s already exists in the %s vschema", - targetTableName, targetKeyspace) - } - } else { - targetVSchema.Tables[targetTableName] = targetTable - targetChanged = true - } - - if targetChanged { - cancelFunc = func() error { - // Restore the original target vschema. - return s.ts.SaveVSchema(ctx, targetKeyspace, ogTargetVSchema) - } - } - - ms = &vtctldatapb.MaterializeSettings{ - Workflow: workflow, - MaterializationIntent: vtctldatapb.MaterializationIntent_CREATELOOKUPINDEX, - SourceKeyspace: keyspace, - TargetKeyspace: targetKeyspace, - StopAfterCopy: vindex.Owner != "" && !continueAfterCopyWithOwner, - TableSettings: []*vtctldatapb.TableMaterializeSettings{{ - TargetTable: targetTableName, - SourceExpression: materializeQuery, - CreateDdl: createDDL, - }}, - } - - // Update sourceVSchema - sourceVSchema.Vindexes[vindexName] = vindex - sourceVSchemaTable.ColumnVindexes = append(sourceVSchemaTable.ColumnVindexes, sourceTable.ColumnVindexes[0]) - - return ms, sourceVSchema, targetVSchema, cancelFunc, nil -} - -func generateColDef(lines []string, sourceVindexCol, vindexFromCol string) (string, error) { - source := sqlescape.EscapeID(sourceVindexCol) - target := sqlescape.EscapeID(vindexFromCol) - - for _, line := range lines[1:] { - if strings.Contains(line, source) { - line = strings.Replace(line, source, target, 1) - line = strings.Replace(line, " AUTO_INCREMENT", "", 1) - line = strings.Replace(line, " DEFAULT NULL", "", 1) - // Ensure that the column definition ends with a comma as we will - // be appending the TO column and PRIMARY KEY definitions. If the - // souce column here was the last entity defined in the source - // table's definition then it will not already have the comma. - if !strings.HasSuffix(strings.TrimSpace(line), ",") { - line += "," - } - return line, nil - } - } - return "", fmt.Errorf("column %s not found in schema %v", sourceVindexCol, lines) -} - func (s *Server) MigrateCreate(ctx context.Context, req *vtctldatapb.MigrateCreateRequest) (*vtctldatapb.WorkflowStatusResponse, error) { moveTablesCreateRequest := &vtctldatapb.MoveTablesCreateRequest{ Workflow: req.Workflow, diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go index 26d722f1de0..4676b732245 100644 --- a/go/vt/vtctl/workflow/server_test.go +++ b/go/vt/vtctl/workflow/server_test.go @@ -27,7 +27,6 @@ import ( "testing" "time" - "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/encoding/prototext" @@ -35,11 +34,12 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl/tmutils" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vtenv" - "vitess.io/vitess/go/vt/vttablet/tabletmanager/vdiff" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" "vitess.io/vitess/go/vt/vttablet/tmclient" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -191,257 +191,6 @@ func TestCheckReshardingJournalExistsOnTablet(t *testing.T) { } } -// TestVDiffCreate performs some basic tests of the VDiffCreate function -// to ensure that it behaves as expected given a specific request. -func TestVDiffCreate(t *testing.T) { - ctx := context.Background() - workflowName := "wf1" - sourceKeyspace := &testKeyspace{ - KeyspaceName: "source", - ShardNames: []string{"0"}, - } - targetKeyspace := &testKeyspace{ - KeyspaceName: "target", - ShardNames: []string{"-80", "80-"}, - } - env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) - defer env.close() - - tests := []struct { - name string - req *vtctldatapb.VDiffCreateRequest - wantErr string - }{ - { - name: "no values", - req: &vtctldatapb.VDiffCreateRequest{}, - // We did not provide any keyspace or shard. - wantErr: "FindAllShardsInKeyspace() invalid keyspace name: UnescapeID err: invalid input identifier ''", - }, - { - name: "generated UUID", - req: &vtctldatapb.VDiffCreateRequest{ - TargetKeyspace: targetKeyspace.KeyspaceName, - Workflow: workflowName, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.wantErr == "" { - env.tmc.expectVRQueryResultOnKeyspaceTablets(targetKeyspace.KeyspaceName, &queryResult{ - query: "select vrepl_id, table_name, lastpk from _vt.copy_state where vrepl_id in (1) and id in (select max(id) from _vt.copy_state where vrepl_id in (1) group by vrepl_id, table_name)", - result: &querypb.QueryResult{}, - }) - } - got, err := env.ws.VDiffCreate(ctx, tt.req) - if tt.wantErr != "" { - require.EqualError(t, err, tt.wantErr) - return - } - require.NoError(t, err) - require.NotNil(t, got) - // Ensure that we always use a valid UUID. - err = uuid.Validate(got.UUID) - require.NoError(t, err) - }) - } -} - -func TestVDiffResume(t *testing.T) { - ctx := context.Background() - sourceKeyspace := &testKeyspace{ - KeyspaceName: "sourceks", - ShardNames: []string{"0"}, - } - targetKeyspace := &testKeyspace{ - KeyspaceName: "targetks", - ShardNames: []string{"-80", "80-"}, - } - workflow := "testwf" - uuid := uuid.New().String() - env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) - defer env.close() - - env.tmc.strict = true - action := string(vdiff.ResumeAction) - - tests := []struct { - name string - req *vtctldatapb.VDiffResumeRequest // vtctld requests - expectedVDiffRequests map[*topodatapb.Tablet]*vdiffRequestResponse // tablet requests - wantErr string - }{ - { - name: "basic resume", // Both target shards - req: &vtctldatapb.VDiffResumeRequest{ - TargetKeyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Uuid: uuid, - }, - expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ - env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { - req: &tabletmanagerdatapb.VDiffRequest{ - Keyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Action: action, - VdiffUuid: uuid, - }, - }, - env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID+tabletUIDStep]: { - req: &tabletmanagerdatapb.VDiffRequest{ - Keyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Action: action, - VdiffUuid: uuid, - }, - }, - }, - }, - { - name: "resume on first shard", - req: &vtctldatapb.VDiffResumeRequest{ - TargetKeyspace: targetKeyspace.KeyspaceName, - TargetShards: targetKeyspace.ShardNames[:1], - Workflow: workflow, - Uuid: uuid, - }, - expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ - env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { - req: &tabletmanagerdatapb.VDiffRequest{ - Keyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Action: action, - VdiffUuid: uuid, - }, - }, - }, - }, - { - name: "resume on invalid shard", - req: &vtctldatapb.VDiffResumeRequest{ - TargetKeyspace: targetKeyspace.KeyspaceName, - TargetShards: []string{"0"}, - Workflow: workflow, - Uuid: uuid, - }, - wantErr: fmt.Sprintf("specified target shard 0 not a valid target for workflow %s", workflow), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - for tab, vdr := range tt.expectedVDiffRequests { - env.tmc.expectVDiffRequest(tab, vdr) - } - got, err := env.ws.VDiffResume(ctx, tt.req) - if tt.wantErr != "" { - require.EqualError(t, err, tt.wantErr) - } else { - require.NoError(t, err) - require.NotNil(t, got) - } - env.tmc.confirmVDiffRequests(t) - }) - } -} - -func TestVDiffStop(t *testing.T) { - ctx := context.Background() - sourceKeyspace := &testKeyspace{ - KeyspaceName: "sourceks", - ShardNames: []string{"0"}, - } - targetKeyspace := &testKeyspace{ - KeyspaceName: "targetks", - ShardNames: []string{"-80", "80-"}, - } - workflow := "testwf" - uuid := uuid.New().String() - env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) - defer env.close() - - env.tmc.strict = true - action := string(vdiff.StopAction) - - tests := []struct { - name string - req *vtctldatapb.VDiffStopRequest // vtctld requests - expectedVDiffRequests map[*topodatapb.Tablet]*vdiffRequestResponse // tablet requests - wantErr string - }{ - { - name: "basic stop", // Both target shards - req: &vtctldatapb.VDiffStopRequest{ - TargetKeyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Uuid: uuid, - }, - expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ - env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { - req: &tabletmanagerdatapb.VDiffRequest{ - Keyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Action: action, - VdiffUuid: uuid, - }, - }, - env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID+tabletUIDStep]: { - req: &tabletmanagerdatapb.VDiffRequest{ - Keyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Action: action, - VdiffUuid: uuid, - }, - }, - }, - }, - { - name: "stop on first shard", - req: &vtctldatapb.VDiffStopRequest{ - TargetKeyspace: targetKeyspace.KeyspaceName, - TargetShards: targetKeyspace.ShardNames[:1], - Workflow: workflow, - Uuid: uuid, - }, - expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ - env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { - req: &tabletmanagerdatapb.VDiffRequest{ - Keyspace: targetKeyspace.KeyspaceName, - Workflow: workflow, - Action: action, - VdiffUuid: uuid, - }, - }, - }, - }, - { - name: "stop on invalid shard", - req: &vtctldatapb.VDiffStopRequest{ - TargetKeyspace: targetKeyspace.KeyspaceName, - TargetShards: []string{"0"}, - Workflow: workflow, - Uuid: uuid, - }, - wantErr: fmt.Sprintf("specified target shard 0 not a valid target for workflow %s", workflow), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - for tab, vdr := range tt.expectedVDiffRequests { - env.tmc.expectVDiffRequest(tab, vdr) - } - got, err := env.ws.VDiffStop(ctx, tt.req) - if tt.wantErr != "" { - require.EqualError(t, err, tt.wantErr) - } else { - require.NoError(t, err) - require.NotNil(t, got) - } - env.tmc.confirmVDiffRequests(t) - }) - } -} - func TestMoveTablesComplete(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -994,11 +743,14 @@ func TestWorkflowDelete(t *testing.T) { }, }, preFunc: func(t *testing.T, env *testEnv) { - err := env.ts.SaveVSchema(ctx, targetKeyspaceName, &vschemapb.Keyspace{ - Sharded: true, - MultiTenantSpec: &vschemapb.MultiTenantSpec{ - TenantIdColumnName: "tenant_id", - TenantIdColumnType: sqltypes.Int64, + err := env.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKeyspaceName, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + MultiTenantSpec: &vschemapb.MultiTenantSpec{ + TenantIdColumnName: "tenant_id", + TenantIdColumnType: sqltypes.Int64, + }, }, }) require.NoError(t, err) @@ -1104,11 +856,14 @@ func TestWorkflowDelete(t *testing.T) { }, }, preFunc: func(t *testing.T, env *testEnv) { - err := env.ts.SaveVSchema(ctx, targetKeyspaceName, &vschemapb.Keyspace{ - Sharded: true, - MultiTenantSpec: &vschemapb.MultiTenantSpec{ - TenantIdColumnName: "tenant_id", - TenantIdColumnType: sqltypes.Int64, + err := env.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKeyspaceName, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + MultiTenantSpec: &vschemapb.MultiTenantSpec{ + TenantIdColumnName: "tenant_id", + TenantIdColumnType: sqltypes.Int64, + }, }, }) require.NoError(t, err) @@ -1164,11 +919,14 @@ func TestWorkflowDelete(t *testing.T) { }, }, preFunc: func(t *testing.T, env *testEnv) { - err := env.ts.SaveVSchema(ctx, targetKeyspaceName, &vschemapb.Keyspace{ - Sharded: true, - MultiTenantSpec: &vschemapb.MultiTenantSpec{ - TenantIdColumnName: "tenant_id", - TenantIdColumnType: sqltypes.Int64, + err := env.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKeyspaceName, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + MultiTenantSpec: &vschemapb.MultiTenantSpec{ + TenantIdColumnName: "tenant_id", + TenantIdColumnType: sqltypes.Int64, + }, }, }) require.NoError(t, err) @@ -2559,3 +2317,83 @@ func TestWorkflowStatus(t *testing.T) { assert.Equal(t, float32(50), stateTable1.RowsPercentage) assert.Equal(t, float32(50), stateTable2.RowsPercentage) } + +func TestDeleteShard(t *testing.T) { + ctx := context.Background() + + sourceKeyspace := &testKeyspace{"source_keyspace", []string{"-"}} + targetKeyspace := &testKeyspace{"target_keyspace", []string{"-"}} + + te := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer te.close() + + // Verify that shard exists. + si, err := te.ts.GetShard(ctx, targetKeyspace.KeyspaceName, targetKeyspace.ShardNames[0]) + require.NoError(t, err) + require.NotNil(t, si) + + // Expect to fail if recursive is false. + err = te.ws.DeleteShard(ctx, targetKeyspace.KeyspaceName, targetKeyspace.ShardNames[0], false, true) + assert.ErrorContains(t, err, "shard target_keyspace/- still has 1 tablets in cell") + + // Should not throw error if given keyspace or shard is invalid. + err = te.ws.DeleteShard(ctx, "invalid_keyspace", "-", false, true) + assert.NoError(t, err) + + // Successful shard delete. + err = te.ws.DeleteShard(ctx, targetKeyspace.KeyspaceName, targetKeyspace.ShardNames[0], true, true) + assert.NoError(t, err) + + // Check if the shard was deleted. + _, err = te.ts.GetShard(ctx, targetKeyspace.KeyspaceName, targetKeyspace.ShardNames[0]) + assert.ErrorContains(t, err, "node doesn't exist") +} + +func TestCopySchemaShard(t *testing.T) { + ctx := context.Background() + + sourceKeyspace := &testKeyspace{"source_keyspace", []string{"-"}} + targetKeyspace := &testKeyspace{"target_keyspace", []string{"-"}} + + te := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer te.close() + + sqlSchema := `create table t1(id bigint(20) unsigned auto_increment, msg varchar(64), primary key (id)) Engine=InnoDB;` + te.tmc.schema[fmt.Sprintf("%s.t1", sourceKeyspace.KeyspaceName)] = &tabletmanagerdatapb.SchemaDefinition{ + DatabaseSchema: "CREATE DATABASE {{.DatabaseName}}", + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Schema: sqlSchema, + Columns: []string{ + "id", + "msg", + }, + Type: tmutils.TableBaseTable, + }, + }, + } + + // Expect queries on target shards + te.tmc.expectApplySchemaRequest(200, &applySchemaRequestResponse{ + change: &tmutils.SchemaChange{ + SQL: "CREATE DATABASE `vt_target_keyspace`", + Force: false, + AllowReplication: true, + SQLMode: vreplication.SQLMode, + }, + }) + te.tmc.expectApplySchemaRequest(200, &applySchemaRequestResponse{ + change: &tmutils.SchemaChange{ + SQL: sqlSchema, + Force: false, + AllowReplication: true, + SQLMode: vreplication.SQLMode, + }, + }) + + sourceTablet := te.tablets[sourceKeyspace.KeyspaceName][100] + err := te.ws.CopySchemaShard(ctx, sourceTablet.Alias, []string{"/.*/"}, nil, false, targetKeyspace.KeyspaceName, "-", 1*time.Second, true) + assert.NoError(t, err) + assert.Empty(t, te.tmc.applySchemaRequests[200]) +} diff --git a/go/vt/vtctl/workflow/switcher_dry_run_test.go b/go/vt/vtctl/workflow/switcher_dry_run_test.go new file mode 100644 index 00000000000..ff0bc709fd4 --- /dev/null +++ b/go/vt/vtctl/workflow/switcher_dry_run_test.go @@ -0,0 +1,390 @@ +/* +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" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +func newTrafficSwitcherEnv(t *testing.T, tables []string, sourceKeyspaceName string, sourceShards []string, targetKeyspaceName string, targetShards []string, workflowName string) (*testEnv, *trafficSwitcher) { + ctx := context.Background() + schema := map[string]*tabletmanagerdatapb.SchemaDefinition{} + for _, tableName := range tables { + schema[tableName] = &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }, + }, + } + } + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: sourceShards, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: targetShards, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + return env, ts +} + +func TestDropTargetVReplicationStreams(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1"}, "sourceks", []string{"0"}, "targetks", []string{"-80", "80-"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.dropTargetVReplicationStreams(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + // Make sure both the target streams are included in the logs + assert.Contains(t, log, "-80") + assert.Contains(t, log, "80-") +} + +func TestStartReverseVReplication(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1"}, "sourceks", []string{"-80", "80-"}, "targetks", []string{"0"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.startReverseVReplication(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + // Make sure both the source tablets are included in the logs + assert.Contains(t, log, "tablet:100") + assert.Contains(t, log, "tablet:110") +} + +func TestRemoveSourceTables(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1"}, "sourceks", []string{"-80", "80-"}, "targetks", []string{"0"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.removeSourceTables(ctx, RenameTable) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + assert.Contains(t, log, "Renaming") + // Make sure both the source tablets are included in the logs + assert.Contains(t, log, "tablet:100") + assert.Contains(t, log, "tablet:110") + + err = dr.removeSourceTables(ctx, DropTable) + require.NoError(t, err) + require.Len(t, drLog.logs, 2) + log = drLog.logs[1] + + assert.Contains(t, log, "Dropping") + // Make sure both the source tablets are included in the logs + assert.Contains(t, log, "tablet:100") + assert.Contains(t, log, "tablet:110") +} + +func TestDropShards(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1"}, "sourceks", []string{"-80", "80-"}, "targetks", []string{"0"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.dropSourceShards(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + // Make sure both the source shards are included in the logs + assert.Contains(t, log, "[-80]") + assert.Contains(t, log, "[80-]") + + err = dr.dropTargetShards(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 2) + log = drLog.logs[1] + assert.Contains(t, log, "[0]") +} + +func TestDropSourceReverseVReplicationStreams(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1"}, "sourceks", []string{"-80", "80-"}, "targetks", []string{"0"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.dropSourceReverseVReplicationStreams(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + // Make sure both the source streams are included in the logs + assert.Contains(t, log, "-80") + assert.Contains(t, log, "80-") + assert.Contains(t, log, "wf1_reverse") +} + +func TestDropSourceDeniedTables(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1", "t2"}, "sourceks", []string{"-80", "80-"}, "targetks", []string{"0"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.dropSourceDeniedTables(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + // Make sure both the source streams are included in the logs + assert.Contains(t, log, "-80") + assert.Contains(t, log, "80-") + // Make sure both the tables are included in the logs + assert.Contains(t, log, "t1") + assert.Contains(t, log, "t2") +} + +func TestDropTargetDeniedTables(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1", "t2"}, "sourceks", []string{"0"}, "targetks", []string{"-80", "80-"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.dropTargetDeniedTables(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + // Make sure both the target streams are included in the logs + assert.Contains(t, log, "-80") + assert.Contains(t, log, "80-") + // Make sure both the tables are included in the logs + assert.Contains(t, log, "t1") + assert.Contains(t, log, "t2") +} + +func TestRemoveTargetTables(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + env, ts := newTrafficSwitcherEnv(t, []string{"t1", "t2"}, "sourceks", []string{"0"}, "targetks", []string{"-80", "80-"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.removeTargetTables(ctx) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + + assert.Contains(t, log, "targetks") + // Make sure both the target streams are included in the logs + assert.Contains(t, log, "-80") + assert.Contains(t, log, "80-") + // Make sure both the tables are included in the logs + assert.Contains(t, log, "t1") + assert.Contains(t, log, "t2") +} + +func TestSwitchKeyspaceReads(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + env, ts := newTrafficSwitcherEnv(t, []string{"t1", "t2"}, sourceKeyspaceName, []string{"0"}, targetKeyspaceName, []string{"-80", "80-"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.switchKeyspaceReads(ctx, []topodatapb.TabletType{topodatapb.TabletType_PRIMARY, topodatapb.TabletType_RDONLY}) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + assert.Contains(t, log, fmt.Sprintf("keyspace %s to keyspace %s", sourceKeyspaceName, targetKeyspaceName)) + assert.Contains(t, log, "PRIMARY") + assert.Contains(t, log, "RDONLY") +} + +func TestSwitchShardReads(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + env, ts := newTrafficSwitcherEnv(t, []string{"t1", "t2"}, sourceKeyspaceName, []string{"0"}, targetKeyspaceName, []string{"-80", "80-"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + err := dr.switchShardReads(ctx, nil, []topodatapb.TabletType{topodatapb.TabletType_PRIMARY, topodatapb.TabletType_RDONLY}, DirectionForward) + require.NoError(t, err) + require.Len(t, drLog.logs, 1) + log := drLog.logs[0] + assert.Contains(t, log, fmt.Sprintf("keyspace %s to keyspace %s", sourceKeyspaceName, targetKeyspaceName)) + assert.Contains(t, log, "-80") + assert.Contains(t, log, "80-") + assert.Contains(t, log, "[0]") + + err = dr.switchShardReads(ctx, nil, []topodatapb.TabletType{topodatapb.TabletType_PRIMARY, topodatapb.TabletType_RDONLY}, DirectionBackward) + require.NoError(t, err) + require.Len(t, drLog.logs, 2) + log = drLog.logs[1] + // Ensure the reverse direction is logged. + assert.Contains(t, log, fmt.Sprintf("keyspace %s to keyspace %s", targetKeyspaceName, sourceKeyspaceName)) + assert.Contains(t, log, "-80") + assert.Contains(t, log, "80-") + assert.Contains(t, log, "[0]") +} + +func TestChangeRouting(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + env, ts := newTrafficSwitcherEnv(t, []string{"t1", "t2"}, sourceKeyspaceName, []string{"0"}, targetKeyspaceName, []string{"-80", "80-"}, "wf1") + defer env.close() + + drLog := NewLogRecorder() + dr := switcherDryRun{ + ts: ts, + drLog: drLog, + } + + ts.migrationType = binlogdatapb.MigrationType_TABLES + err := dr.changeRouting(ctx) + require.NoError(t, err) + assert.Len(t, drLog.logs, 2) + assert.Contains(t, drLog.logs[0], fmt.Sprintf("keyspace %s to keyspace %s", sourceKeyspaceName, targetKeyspaceName)) + assert.Contains(t, drLog.logs[1], "t1") + assert.Contains(t, drLog.logs[1], "t2") + + ts.migrationType = binlogdatapb.MigrationType_SHARDS + err = dr.changeRouting(ctx) + require.NoError(t, err) + assert.Len(t, drLog.logs, 5) + assert.Contains(t, drLog.logs[3], "false") + assert.Contains(t, drLog.logs[3], "shard:0") + assert.Contains(t, drLog.logs[4], "true") + assert.Contains(t, drLog.logs[4], "shard:-80") + assert.Contains(t, drLog.logs[4], "shard:80-") +} + +func TestDRInitializeTargetSequences(t *testing.T) { + ctx := context.Background() + drLog := NewLogRecorder() + dr := &switcherDryRun{ + drLog: drLog, + } + + tables := map[string]*sequenceMetadata{ + "t1": nil, + "t2": nil, + "t3": nil, + } + err := dr.initializeTargetSequences(ctx, tables) + require.NoError(t, err) + assert.Len(t, drLog.logs, 1) + assert.Contains(t, drLog.logs[0], "t1") + assert.Contains(t, drLog.logs[0], "t2") + assert.Contains(t, drLog.logs[0], "t3") +} diff --git a/go/vt/vtctl/workflow/traffic_switcher.go b/go/vt/vtctl/workflow/traffic_switcher.go index 937dffe70b3..3b151103d7f 100644 --- a/go/vt/vtctl/workflow/traffic_switcher.go +++ b/go/vt/vtctl/workflow/traffic_switcher.go @@ -409,7 +409,7 @@ func (ts *trafficSwitcher) addParticipatingTablesToKeyspace(ctx context.Context, vschema.Tables[table] = &vschemapb.Table{} } } - return ts.TopoServer().SaveVSchema(ctx, keyspace, vschema) + return ts.TopoServer().SaveVSchema(ctx, vschema) } func (ts *trafficSwitcher) deleteRoutingRules(ctx context.Context) error { @@ -538,7 +538,7 @@ func (ts *trafficSwitcher) dropParticipatingTablesFromKeyspace(ctx context.Conte for _, tableName := range ts.Tables() { delete(vschema.Tables, tableName) } - return ts.TopoServer().SaveVSchema(ctx, keyspace, vschema) + return ts.TopoServer().SaveVSchema(ctx, vschema) } func (ts *trafficSwitcher) removeSourceTables(ctx context.Context, removalType TableRemovalType) error { @@ -1013,7 +1013,7 @@ func (ts *trafficSwitcher) buildTenantPredicate(ctx context.Context) (*sqlparser if err != nil { return nil, err } - targetVSchema, err := vindexes.BuildKeyspaceSchema(vschema, ts.targetKeyspace, parser) + targetVSchema, err := vindexes.BuildKeyspaceSchema(vschema.Keyspace, ts.targetKeyspace, parser) if err != nil { return nil, err } @@ -1135,30 +1135,45 @@ func (ts *trafficSwitcher) switchDeniedTables(ctx context.Context) error { return nil } +// cancelMigration attempts to revert all changes made during the migration so that we can get back to the +// state when traffic switching (or reversing) was initiated. func (ts *trafficSwitcher) cancelMigration(ctx context.Context, sm *StreamMigrator) { var err error + + if ctx.Err() != nil { + // Even though we create a new context later on we still record any context error: + // for forensics in case of failures. + ts.Logger().Infof("In Cancel migration: original context invalid: %s", ctx.Err()) + } + + // We create a new context while canceling the migration, so that we are independent of the original + // context being cancelled prior to or during the cancel operation. + cmTimeout := 60 * time.Second + cmCtx, cmCancel := context.WithTimeout(context.Background(), cmTimeout) + defer cmCancel() + if ts.MigrationType() == binlogdatapb.MigrationType_TABLES { - err = ts.switchDeniedTables(ctx) + err = ts.switchDeniedTables(cmCtx) } else { - err = ts.changeShardsAccess(ctx, ts.SourceKeyspaceName(), ts.SourceShards(), allowWrites) + err = ts.changeShardsAccess(cmCtx, ts.SourceKeyspaceName(), ts.SourceShards(), allowWrites) } if err != nil { - ts.Logger().Errorf("Cancel migration failed: %v", err) + ts.Logger().Errorf("Cancel migration failed: could not revert denied tables / shard access: %v", err) } - sm.CancelStreamMigrations(ctx) + sm.CancelStreamMigrations(cmCtx) err = ts.ForAllTargets(func(target *MigrationTarget) error { query := fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name=%s and workflow=%s", encodeString(target.GetPrimary().DbName()), encodeString(ts.WorkflowName())) - _, err := ts.TabletManagerClient().VReplicationExec(ctx, target.GetPrimary().Tablet, query) + _, err := ts.TabletManagerClient().VReplicationExec(cmCtx, target.GetPrimary().Tablet, query) return err }) if err != nil { ts.Logger().Errorf("Cancel migration failed: could not restart vreplication: %v", err) } - err = ts.deleteReverseVReplication(ctx) + err = ts.deleteReverseVReplication(cmCtx) if err != nil { ts.Logger().Errorf("Cancel migration failed: could not delete reverse vreplication streams: %v", err) } @@ -1426,7 +1441,7 @@ func (ts *trafficSwitcher) getTargetSequenceMetadata(ctx context.Context) (map[s return nil, nil } - sequencesByBackingTable, backingTablesFound, err := ts.findSequenceUsageInKeyspace(vschema) + sequencesByBackingTable, backingTablesFound, err := ts.findSequenceUsageInKeyspace(vschema.Keyspace) if err != nil { return nil, err } @@ -1594,7 +1609,7 @@ func (ts trafficSwitcher) createMissingSequenceTables(ctx context.Context, seque } } if updatedGlobalVSchema { - err = ts.ws.ts.SaveVSchema(ctx, globalKeyspace, globalVSchema) + err = ts.ws.ts.SaveVSchema(ctx, globalVSchema) if err != nil { return vterrors.Wrapf(err, "failed to update vschema in the global-keyspace %s", globalKeyspace) } diff --git a/go/vt/vtctl/workflow/traffic_switcher_test.go b/go/vt/vtctl/workflow/traffic_switcher_test.go index 325b405b6f0..a7da91174b9 100644 --- a/go/vt/vtctl/workflow/traffic_switcher_test.go +++ b/go/vt/vtctl/workflow/traffic_switcher_test.go @@ -28,7 +28,9 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqlescape" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + "vitess.io/vitess/go/vt/proto/binlogdata" "vitess.io/vitess/go/vt/proto/vschema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" @@ -36,6 +38,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -532,9 +535,15 @@ func TestGetTargetSequenceMetadata(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - err := env.ts.SaveVSchema(ctx, sourceKeyspace.KeyspaceName, tc.sourceVSchema) + err := env.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: sourceKeyspace.KeyspaceName, + Keyspace: tc.sourceVSchema, + }) require.NoError(t, err) - err = env.ts.SaveVSchema(ctx, targetKeyspace.KeyspaceName, tc.targetVSchema) + err = env.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKeyspace.KeyspaceName, + Keyspace: tc.targetVSchema, + }) require.NoError(t, err) err = env.ts.RebuildSrvVSchema(ctx, nil) require.NoError(t, err) @@ -649,3 +658,378 @@ func TestTrafficSwitchPositionHandling(t *testing.T) { }) require.NoError(t, err) } + +func TestInitializeTargetSequences(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{ + tableName: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }, + }, + }, + } + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + sw := &switcher{ts: ts, s: env.ws} + + sequencesByBackingTable := map[string]*sequenceMetadata{ + "my-seq1": { + backingTableName: "my-seq1", + backingTableKeyspace: sourceKeyspaceName, + backingTableDBName: fmt.Sprintf("vt_%s", sourceKeyspaceName), + usingTableName: tableName, + usingTableDBName: "vt_targetks", + usingTableDefinition: &vschema.Table{ + AutoIncrement: &vschema.AutoIncrement{ + Column: "my-col", + Sequence: fmt.Sprintf("%s.my-seq1", sourceKeyspace.KeyspaceName), + }, + }, + }, + } + + env.tmc.expectVRQuery(200, "/select max.*", sqltypes.MakeTestResult(sqltypes.MakeTestFields("maxval", "int64"), "34")) + // Expect the insert query to be executed with 35 as a params, since we provide a maxID of 34 in the last query + env.tmc.expectVRQuery(100, "/insert into.*35.*", &sqltypes.Result{RowsAffected: 1}) + + err = sw.initializeTargetSequences(ctx, sequencesByBackingTable) + assert.NoError(t, err) + + // Expect the queries to be cleared + assert.Empty(t, env.tmc.vrQueries[100]) + assert.Empty(t, env.tmc.vrQueries[200]) +} + +func TestAddTenantFilter(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + } + + 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), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + err := env.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKeyspaceName, + Keyspace: &vschema.Keyspace{ + MultiTenantSpec: &vschema.MultiTenantSpec{ + TenantIdColumnName: "tenant_id", + TenantIdColumnType: sqltypes.Int64, + }, + }, + }) + require.NoError(t, err) + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + + ts.options.TenantId = "123" + + filter, err := ts.addTenantFilter(ctx, fmt.Sprintf("select * from %s where id < 5", tableName)) + assert.NoError(t, err) + assert.Equal(t, "select * from t1 where tenant_id = 123 and id < 5", filter) +} + +func TestChangeShardRouting(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + } + + 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), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + + err = env.ws.ts.UpdateSrvKeyspace(ctx, "cell", targetKeyspaceName, &topodatapb.SrvKeyspace{ + Partitions: []*topodatapb.SrvKeyspace_KeyspacePartition{ + { + ShardReferences: []*topodatapb.ShardReference{ + { + Name: "0", + }, + }, + }, + }, + }) + require.NoError(t, err) + + err = env.ws.ts.UpdateSrvKeyspace(ctx, "cell", sourceKeyspaceName, &topodatapb.SrvKeyspace{ + Partitions: []*topodatapb.SrvKeyspace_KeyspacePartition{ + { + ShardReferences: []*topodatapb.ShardReference{ + { + Name: "0", + }, + }, + }, + }, + }) + require.NoError(t, err) + + ctx, _, err = env.ws.ts.LockShard(ctx, targetKeyspaceName, "0", "targetks0") + require.NoError(t, err) + + ctx, _, err = env.ws.ts.LockKeyspace(ctx, targetKeyspaceName, "targetks0") + require.NoError(t, err) + + err = ts.changeShardRouting(ctx) + assert.NoError(t, err) + + sourceShardInfo, err := env.ws.ts.GetShard(ctx, sourceKeyspaceName, "0") + assert.NoError(t, err) + assert.False(t, sourceShardInfo.IsPrimaryServing, "source shard shouldn't have it's primary serving after changeShardRouting() is called.") + + targetShardInfo, err := env.ws.ts.GetShard(ctx, targetKeyspaceName, "0") + assert.NoError(t, err) + assert.True(t, targetShardInfo.IsPrimaryServing, "target shard should have it's primary serving after changeShardRouting() is called.") +} + +func TestAddParticipatingTablesToKeyspace(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + } + + 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), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + + err = ts.addParticipatingTablesToKeyspace(ctx, sourceKeyspaceName, "") + assert.NoError(t, err) + + vs, err := env.ts.GetVSchema(ctx, sourceKeyspaceName) + assert.NoError(t, err) + assert.NotNil(t, vs.Tables["t1"]) + assert.Empty(t, vs.Tables["t1"]) + + specs := `{"t1":{"column_vindexes":[{"column":"col1","name":"v1"}, {"column":"col2","name":"v2"}]},"t2":{"column_vindexes":[{"column":"col2","name":"v2"}]}}` + err = ts.addParticipatingTablesToKeyspace(ctx, sourceKeyspaceName, specs) + assert.NoError(t, err) + + vs, err = env.ts.GetVSchema(ctx, sourceKeyspaceName) + assert.NoError(t, err) + require.NotNil(t, vs.Tables["t1"]) + require.NotNil(t, vs.Tables["t2"]) + assert.Len(t, vs.Tables["t1"].ColumnVindexes, 2) + assert.Len(t, vs.Tables["t2"].ColumnVindexes, 1) +} + +func TestCancelMigration_TABLES(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: "sourceks", + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: "targetks", + ShardNames: []string{"0"}, + } + + 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), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspace.KeyspaceName, workflowName) + require.NoError(t, err) + + sm, err := BuildStreamMigrator(ctx, ts, false, sqlparser.NewTestParser()) + require.NoError(t, err) + + env.tmc.expectVRQuery(200, "update _vt.vreplication set state='Running', message='' where db_name='vt_targetks' and workflow='wf1'", &sqltypes.Result{}) + env.tmc.expectVRQuery(100, "delete from _vt.vreplication where db_name = 'vt_sourceks' and workflow = 'wf1_reverse'", &sqltypes.Result{}) + + ctx, _, err = env.ts.LockKeyspace(ctx, targetKeyspace.KeyspaceName, "test") + require.NoError(t, err) + + ctx, _, err = env.ts.LockKeyspace(ctx, sourceKeyspace.KeyspaceName, "test") + require.NoError(t, err) + + err = topo.CheckKeyspaceLocked(ctx, ts.targetKeyspace) + require.NoError(t, err) + + err = topo.CheckKeyspaceLocked(ctx, ts.sourceKeyspace) + require.NoError(t, err) + + ts.cancelMigration(ctx, sm) + + // Expect the queries to be cleared + assert.Empty(t, env.tmc.vrQueries[100]) + assert.Empty(t, env.tmc.vrQueries[200]) +} + +func TestCancelMigration_SHARDS(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: "sourceks", + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: "targetks", + ShardNames: []string{"0"}, + } + + 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), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspace.KeyspaceName, workflowName) + require.NoError(t, err) + ts.migrationType = binlogdata.MigrationType_SHARDS + + sm, err := BuildStreamMigrator(ctx, ts, false, sqlparser.NewTestParser()) + require.NoError(t, err) + + env.tmc.expectVRQuery(100, "update /*vt+ ALLOW_UNSAFE_VREPLICATION_WRITE */ _vt.vreplication set state='Running', stop_pos=null, message='' where db_name='vt_sourceks' and workflow != 'wf1_reverse'", &sqltypes.Result{}) + env.tmc.expectVRQuery(200, "update _vt.vreplication set state='Running', message='' where db_name='vt_targetks' and workflow='wf1'", &sqltypes.Result{}) + env.tmc.expectVRQuery(100, "delete from _vt.vreplication where db_name = 'vt_sourceks' and workflow = 'wf1_reverse'", &sqltypes.Result{}) + + ctx, _, err = env.ts.LockKeyspace(ctx, targetKeyspace.KeyspaceName, "test") + require.NoError(t, err) + + ctx, _, err = env.ts.LockKeyspace(ctx, sourceKeyspace.KeyspaceName, "test") + require.NoError(t, err) + + err = topo.CheckKeyspaceLocked(ctx, ts.targetKeyspace) + require.NoError(t, err) + + err = topo.CheckKeyspaceLocked(ctx, ts.sourceKeyspace) + require.NoError(t, err) + + ts.cancelMigration(ctx, sm) + + // Expect the queries to be cleared + assert.Empty(t, env.tmc.vrQueries[100]) + assert.Empty(t, env.tmc.vrQueries[200]) +} diff --git a/go/vt/vtctl/workflow/utils.go b/go/vt/vtctl/workflow/utils.go index 65fa49fde86..3c33ef25560 100644 --- a/go/vt/vtctl/workflow/utils.go +++ b/go/vt/vtctl/workflow/utils.go @@ -51,6 +51,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" 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" ) @@ -1028,7 +1029,7 @@ func applyTargetShards(ts *trafficSwitcher, targetShards []string) error { // validateSourceTablesExist validates that tables provided are present // in the source keyspace. -func validateSourceTablesExist(ctx context.Context, sourceKeyspace string, ksTables, tables []string) error { +func validateSourceTablesExist(sourceKeyspace string, ksTables, tables []string) error { var missingTables []string for _, table := range tables { if schema.IsInternalOperationTableName(table) { @@ -1051,3 +1052,17 @@ func validateSourceTablesExist(ctx context.Context, sourceKeyspace string, ksTab } return nil } + +// getVindexAndVSchema gets the vindex (from VSchema) and VSchema with the +// provided vindex name and keyspace. +func getVindexAndVSchema(ctx context.Context, ts *topo.Server, keyspace string, vindexName string) (*vschemapb.Vindex, *topo.KeyspaceVSchemaInfo, error) { + vschema, err := ts.GetVSchema(ctx, keyspace) + if err != nil { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get vschema for the %s keyspace", keyspace) + } + vindex := vschema.Vindexes[vindexName] + if vindex == nil { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "vindex %s not found in the %s keyspace", vindexName, keyspace) + } + return vindex, vschema, nil +} diff --git a/go/vt/vtctl/workflow/utils_test.go b/go/vt/vtctl/workflow/utils_test.go index 8458cf60995..99850639ac5 100644 --- a/go/vt/vtctl/workflow/utils_test.go +++ b/go/vt/vtctl/workflow/utils_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/require" clientv3 "go.etcd.io/etcd/client/v3" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/testfiles" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/topo" @@ -22,6 +23,7 @@ import ( "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topotools" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -247,7 +249,6 @@ func startEtcd(t *testing.T) string { } func TestValidateSourceTablesExist(t *testing.T) { - ctx := context.Background() ks := "source_keyspace" ksTables := []string{"table1", "table2"} @@ -272,7 +273,7 @@ func TestValidateSourceTablesExist(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - err := validateSourceTablesExist(ctx, ks, ksTables, tc.tables) + err := validateSourceTablesExist(ks, ksTables, tc.tables) if tc.errContains != "" { assert.ErrorContains(t, err, tc.errContains) } else { @@ -281,3 +282,77 @@ func TestValidateSourceTablesExist(t *testing.T) { }) } } + +func TestLegacyBuildTargets(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: "sourceks", + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: "targetks", + ShardNames: []string{"-80", "80-"}, + } + + 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), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + result1 := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message|cell|tablet_types|workflow_type|workflow_sub_type|defer_secondary_keys", + "int64|varchar|varchar|varchar|varchar|int64|int64|int64"), + "1|keyspace:\"source\" shard:\"-80\" filter:{rules:{match:\"t1\"} rules:{match:\"t2\"}}||||0|0|0", + ) + result2 := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message|cell|tablet_types|workflow_type|workflow_sub_type|defer_secondary_keys", + "int64|varchar|varchar|varchar|varchar|int64|int64|int64"), + "1|keyspace:\"source\" shard:\"80-\" filter:{rules:{match:\"t1\"} rules:{match:\"t2\"}}||||0|0|0", + "2|keyspace:\"source\" shard:\"80-\" filter:{rules:{match:\"t3\"} rules:{match:\"t4\"}}||||0|0|0", + ) + env.tmc.expectVRQuery(200, "select id, source, message, cell, tablet_types, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where workflow='wf1' and db_name='vt_targetks'", result1) + env.tmc.expectVRQuery(210, "select id, source, message, cell, tablet_types, workflow_type, workflow_sub_type, defer_secondary_keys from _vt.vreplication where workflow='wf1' and db_name='vt_targetks'", result2) + + ti, err := LegacyBuildTargets(ctx, env.ts, env.tmc, targetKeyspace.KeyspaceName, workflowName, targetKeyspace.ShardNames) + require.NoError(t, err) + // Expect 2 targets as there are 2 target shards. + assert.Len(t, ti.Targets, 2) + + assert.NotNil(t, ti.Targets["-80"]) + assert.NotNil(t, ti.Targets["80-"]) + + t1 := ti.Targets["-80"] + t2 := ti.Targets["80-"] + assert.Len(t, t1.Sources, 1) + assert.Len(t, t2.Sources, 2) + assert.Len(t, t1.Sources[1].Filter.Rules, 2) + + assert.Equal(t, t1.Sources[1].Filter.Rules[0].Match, "t1") + assert.Equal(t, t1.Sources[1].Filter.Rules[1].Match, "t2") + assert.Equal(t, t1.Sources[1].Shard, "-80") + + assert.Len(t, t2.Sources[1].Filter.Rules, 2) + assert.Len(t, t2.Sources[2].Filter.Rules, 2) + + assert.Equal(t, t2.Sources[1].Shard, "80-") + assert.Equal(t, t2.Sources[2].Shard, "80-") + assert.Equal(t, t2.Sources[1].Filter.Rules[0].Match, "t1") + assert.Equal(t, t2.Sources[1].Filter.Rules[1].Match, "t2") + assert.Equal(t, t2.Sources[2].Filter.Rules[0].Match, "t3") + assert.Equal(t, t2.Sources[2].Filter.Rules[1].Match, "t4") +} diff --git a/go/vt/vtctl/workflow/vdiff.go b/go/vt/vtctl/workflow/vdiff.go new file mode 100644 index 00000000000..30953868b0b --- /dev/null +++ b/go/vt/vtctl/workflow/vdiff.go @@ -0,0 +1,571 @@ +/* +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" + "encoding/json" + "math" + "sort" + "strings" + "time" + + "github.com/google/uuid" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/trace" + "vitess.io/vitess/go/vt/discovery" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vdiff" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + vttimepb "vitess.io/vitess/go/vt/proto/vttime" +) + +// TableSummary aggregates the current state of the table diff from all shards. +type TableSummary struct { + TableName string + State vdiff.VDiffState + RowsCompared int64 + MatchingRows int64 + MismatchedRows int64 + ExtraRowsSource int64 + ExtraRowsTarget int64 + LastUpdated string `json:"LastUpdated,omitempty"` +} + +// Summary aggregates the current state of the vdiff from all shards. +type Summary struct { + Workflow, Keyspace string + State vdiff.VDiffState + UUID string + RowsCompared int64 + HasMismatch bool + Shards string + StartedAt string `json:"StartedAt,omitempty"` + CompletedAt string `json:"CompletedAt,omitempty"` + TableSummaryMap map[string]TableSummary `json:"TableSummary,omitempty"` + // This is keyed by table name and then by shard name. + Reports map[string]map[string]vdiff.DiffReport `json:"Reports,omitempty"` + // This is keyed by shard name. + Errors map[string]string `json:"Errors,omitempty"` + Progress *vdiff.ProgressReport `json:"Progress,omitempty"` +} + +// BuildSummary generates a summary from a vdiff show response. +func BuildSummary(keyspace, workflow, uuid string, resp *vtctldatapb.VDiffShowResponse, verbose bool) (*Summary, error) { + summary := &Summary{ + Workflow: workflow, + Keyspace: keyspace, + UUID: uuid, + State: vdiff.UnknownState, + RowsCompared: 0, + StartedAt: "", + CompletedAt: "", + HasMismatch: false, + Shards: "", + Reports: make(map[string]map[string]vdiff.DiffReport), + Errors: make(map[string]string), + Progress: nil, + } + + var tableSummaryMap map[string]TableSummary + var reports map[string]map[string]vdiff.DiffReport + // Keep a tally of the states across all tables in all shards. + tableStateCounts := map[vdiff.VDiffState]int{ + vdiff.UnknownState: 0, + vdiff.PendingState: 0, + vdiff.StartedState: 0, + vdiff.StoppedState: 0, + vdiff.ErrorState: 0, + vdiff.CompletedState: 0, + } + // Keep a tally of the summary states across all shards. + shardStateCounts := map[vdiff.VDiffState]int{ + vdiff.UnknownState: 0, + vdiff.PendingState: 0, + vdiff.StartedState: 0, + vdiff.StoppedState: 0, + vdiff.ErrorState: 0, + vdiff.CompletedState: 0, + } + // Keep a tally of the approximate total rows to process as we'll use this for our progress + // report. + totalRowsToCompare := int64(0) + var shards []string + for shard, resp := range resp.TabletResponses { + first := true + if resp != nil && resp.Output != nil { + shards = append(shards, shard) + qr := sqltypes.Proto3ToResult(resp.Output) + if tableSummaryMap == nil { + tableSummaryMap = make(map[string]TableSummary, 0) + reports = make(map[string]map[string]vdiff.DiffReport, 0) + } + for _, row := range qr.Named().Rows { + // Update the global VDiff summary based on the per shard level summary. + // Since these values will be the same for all subsequent rows we only use + // the first row. + if first { + first = false + // Our timestamps are strings in `2022-06-26 20:43:25` format so we sort + // them lexicographically. + // We should use the earliest started_at across all shards. + if sa := row.AsString("started_at", ""); summary.StartedAt == "" || sa < summary.StartedAt { + summary.StartedAt = sa + } + // And we should use the latest completed_at across all shards. + if ca := row.AsString("completed_at", ""); summary.CompletedAt == "" || ca > summary.CompletedAt { + summary.CompletedAt = ca + } + // If we had an error on the shard, then let's add that to the summary. + if le := row.AsString("last_error", ""); le != "" { + summary.Errors[shard] = le + } + // Keep track of how many shards are marked as a specific state. We check + // this combined with the shard.table states to determine the VDiff summary + // state. + shardStateCounts[vdiff.VDiffState(strings.ToLower(row.AsString("vdiff_state", "")))]++ + } + + // Global VDiff summary updates that take into account the per table details + // per shard. + { + summary.RowsCompared += row.AsInt64("rows_compared", 0) + totalRowsToCompare += row.AsInt64("table_rows", 0) + + // If we had a mismatch on any table on any shard then the global VDiff + // summary does too. + if mm, _ := row.ToBool("has_mismatch"); mm { + summary.HasMismatch = true + } + } + + // Table summary information that must be accounted for across all shards. + { + table := row.AsString("table_name", "") + if table == "" { // This occurs when the table diff has not started on 1 or more shards + continue + } + // Create the global VDiff table summary object if it doesn't exist. + if _, ok := tableSummaryMap[table]; !ok { + tableSummaryMap[table] = TableSummary{ + TableName: table, + State: vdiff.UnknownState, + } + + } + ts := tableSummaryMap[table] + // This is the shard level VDiff table state. + sts := vdiff.VDiffState(strings.ToLower(row.AsString("table_state", ""))) + tableStateCounts[sts]++ + + // The error state must be sticky, and we should not override any other + // known state with completed. + switch sts { + case vdiff.CompletedState: + if ts.State == vdiff.UnknownState { + ts.State = sts + } + case vdiff.ErrorState: + ts.State = sts + default: + if ts.State != vdiff.ErrorState { + ts.State = sts + } + } + + diffReport := row.AsString("report", "") + dr := vdiff.DiffReport{} + if diffReport != "" { + err := json.Unmarshal([]byte(diffReport), &dr) + if err != nil { + return nil, err + } + ts.RowsCompared += dr.ProcessedRows + ts.MismatchedRows += dr.MismatchedRows + ts.MatchingRows += dr.MatchingRows + ts.ExtraRowsTarget += dr.ExtraRowsTarget + ts.ExtraRowsSource += dr.ExtraRowsSource + } + if _, ok := reports[table]; !ok { + reports[table] = make(map[string]vdiff.DiffReport) + } + + reports[table][shard] = dr + tableSummaryMap[table] = ts + } + } + } + } + + // The global VDiff summary should progress from pending->started->completed with + // stopped for any shard and error for any table being sticky for the global summary. + // We should only consider the VDiff to be complete if it's completed for every table + // on every shard. + if shardStateCounts[vdiff.StoppedState] > 0 { + summary.State = vdiff.StoppedState + } else if shardStateCounts[vdiff.ErrorState] > 0 || tableStateCounts[vdiff.ErrorState] > 0 { + summary.State = vdiff.ErrorState + } else if tableStateCounts[vdiff.StartedState] > 0 { + summary.State = vdiff.StartedState + } else if tableStateCounts[vdiff.PendingState] > 0 { + summary.State = vdiff.PendingState + } else if tableStateCounts[vdiff.CompletedState] == (len(tableSummaryMap) * len(shards)) { + // When doing shard consolidations/merges, we cannot rely solely on the + // vdiff_table state as there are N sources that we process rows from sequentially + // with each one writing to the shared _vt.vdiff_table record for the target shard. + // So we only mark the vdiff for the shard as completed when we've finished + // processing rows from all of the sources -- which is recorded by marking the + // vdiff done for the shard by setting _vt.vdiff.state = completed. + if shardStateCounts[vdiff.CompletedState] == len(shards) { + summary.State = vdiff.CompletedState + } else { + summary.State = vdiff.StartedState + } + } else { + summary.State = vdiff.UnknownState + } + + // If the vdiff has been started then we can calculate the progress. + if summary.State == vdiff.StartedState { + summary.Progress = BuildProgressReport(summary.RowsCompared, totalRowsToCompare, summary.StartedAt) + } + + sort.Strings(shards) // Sort for predictable output + summary.Shards = strings.Join(shards, ",") + summary.TableSummaryMap = tableSummaryMap + summary.Reports = reports + if !summary.HasMismatch && !verbose { + summary.Reports = nil + summary.TableSummaryMap = nil + } + // If we haven't completed the global VDiff then be sure to reflect that with no + // CompletedAt value. + if summary.State != vdiff.CompletedState { + summary.CompletedAt = "" + } + return summary, nil +} + +func BuildProgressReport(rowsCompared int64, rowsToCompare int64, startedAt string) *vdiff.ProgressReport { + report := &vdiff.ProgressReport{} + if rowsCompared >= 1 { + // Round to 2 decimal points. + report.Percentage = math.Round(math.Min((float64(rowsCompared)/float64(rowsToCompare))*100, 100.00)*100) / 100 + } + if math.IsNaN(report.Percentage) { + report.Percentage = 0 + } + pctToGo := math.Abs(report.Percentage - 100.00) + startTime, _ := time.Parse(vdiff.TimestampFormat, startedAt) + curTime := time.Now().UTC() + runTime := curTime.Unix() - startTime.Unix() + if report.Percentage >= 1 { + // Calculate how long 1% took, on avg, and multiply that by the % left. + eta := time.Unix(((int64(runTime)/int64(report.Percentage))*int64(pctToGo))+curTime.Unix(), 1).UTC() + // Cap the ETA at 1 year out to prevent providing nonsensical ETAs. + if eta.Before(time.Now().UTC().AddDate(1, 0, 0)) { + report.ETA = eta.Format(vdiff.TimestampFormat) + } + } + return report +} + +// VDiffCreate is part of the vtctlservicepb.VtctldServer interface. +// It passes on the request to the target primary tablets that are +// participating in the given workflow and VDiff. +func (s *Server) VDiffCreate(ctx context.Context, req *vtctldatapb.VDiffCreateRequest) (*vtctldatapb.VDiffCreateResponse, error) { + span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffCreate") + defer span.Finish() + + span.Annotate("keyspace", req.TargetKeyspace) + span.Annotate("workflow", req.Workflow) + span.Annotate("uuid", req.Uuid) + span.Annotate("source_cells", req.SourceCells) + span.Annotate("target_cells", req.TargetCells) + span.Annotate("tablet_types", req.TabletTypes) + span.Annotate("tables", req.Tables) + span.Annotate("auto_retry", req.AutoRetry) + span.Annotate("max_diff_duration", req.MaxDiffDuration) + if req.AutoStart != nil { + span.Annotate("auto_start", req.GetAutoStart()) + } + + var err error + req.Uuid = strings.TrimSpace(req.Uuid) + if req.Uuid == "" { // Generate a UUID + req.Uuid = uuid.New().String() + } else { // Validate UUID if provided + if err = uuid.Validate(req.Uuid); err != nil { + return nil, vterrors.Wrapf(err, "invalid UUID provided: %s", req.Uuid) + } + } + + tabletTypesStr := discovery.BuildTabletTypesString(req.TabletTypes, req.TabletSelectionPreference) + + if req.Limit == 0 { // This would produce no useful results + req.Limit = math.MaxInt64 + } + // This is a pointer so there's no ZeroValue in the message + // and an older v18 client will not provide it. + if req.MaxDiffDuration == nil { + req.MaxDiffDuration = &vttimepb.Duration{} + } + // The other vttime.Duration vars should not be nil as the + // client should always provide them, but we check anyway to + // be safe. + if req.FilteredReplicationWaitTime == nil { + // A value of 0 is not valid as the vdiff will never succeed. + req.FilteredReplicationWaitTime = &vttimepb.Duration{ + Seconds: int64(DefaultTimeout.Seconds()), + } + } + if req.WaitUpdateInterval == nil { + req.WaitUpdateInterval = &vttimepb.Duration{} + } + + autoStart := true + if req.AutoStart != nil { + autoStart = req.GetAutoStart() + } + + options := &tabletmanagerdatapb.VDiffOptions{ + PickerOptions: &tabletmanagerdatapb.VDiffPickerOptions{ + TabletTypes: tabletTypesStr, + SourceCell: strings.Join(req.SourceCells, ","), + TargetCell: strings.Join(req.TargetCells, ","), + }, + CoreOptions: &tabletmanagerdatapb.VDiffCoreOptions{ + Tables: strings.Join(req.Tables, ","), + AutoRetry: req.AutoRetry, + MaxRows: req.Limit, + TimeoutSeconds: req.FilteredReplicationWaitTime.Seconds, + MaxExtraRowsToCompare: req.MaxExtraRowsToCompare, + UpdateTableStats: req.UpdateTableStats, + MaxDiffSeconds: req.MaxDiffDuration.Seconds, + AutoStart: &autoStart, + }, + ReportOptions: &tabletmanagerdatapb.VDiffReportOptions{ + OnlyPks: req.OnlyPKs, + DebugQuery: req.DebugQuery, + MaxSampleRows: req.MaxReportSampleRows, + RowDiffColumnTruncateAt: req.RowDiffColumnTruncateAt, + }, + } + + tabletreq := &tabletmanagerdatapb.VDiffRequest{ + Keyspace: req.TargetKeyspace, + Workflow: req.Workflow, + Action: string(vdiff.CreateAction), + Options: options, + VdiffUuid: req.Uuid, + } + + ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) + if err != nil { + return nil, err + } + if ts.frozen { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "invalid VDiff run: writes have been already been switched for workflow %s.%s", + req.TargetKeyspace, req.Workflow) + } + + workflowStatus, err := s.getWorkflowStatus(ctx, req.TargetKeyspace, req.Workflow) + if err != nil { + return nil, err + } + if workflowStatus != binlogdatapb.VReplicationWorkflowState_Running { + s.Logger().Infof("Workflow %s.%s is not running, cannot start VDiff in state %s", req.TargetKeyspace, req.Workflow, workflowStatus) + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, + "not all streams are running in workflow %s.%s", req.TargetKeyspace, req.Workflow) + } + + err = ts.ForAllTargets(func(target *MigrationTarget) error { + _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) + return err + }) + if err != nil { + s.Logger().Errorf("Error executing vdiff create action: %v", err) + return nil, err + } + + return &vtctldatapb.VDiffCreateResponse{ + UUID: req.Uuid, + }, nil +} + +// VDiffDelete is part of the vtctlservicepb.VtctldServer interface. +func (s *Server) VDiffDelete(ctx context.Context, req *vtctldatapb.VDiffDeleteRequest) (*vtctldatapb.VDiffDeleteResponse, error) { + span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffDelete") + defer span.Finish() + + span.Annotate("keyspace", req.TargetKeyspace) + span.Annotate("workflow", req.Workflow) + span.Annotate("argument", req.Arg) + + tabletreq := &tabletmanagerdatapb.VDiffRequest{ + Keyspace: req.TargetKeyspace, + Workflow: req.Workflow, + Action: string(vdiff.DeleteAction), + ActionArg: req.Arg, + } + + ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) + if err != nil { + return nil, err + } + + err = ts.ForAllTargets(func(target *MigrationTarget) error { + _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) + return err + }) + if err != nil { + s.Logger().Errorf("Error executing vdiff delete action: %v", err) + return nil, err + } + + return &vtctldatapb.VDiffDeleteResponse{}, nil +} + +// VDiffResume is part of the vtctlservicepb.VtctldServer interface. +func (s *Server) VDiffResume(ctx context.Context, req *vtctldatapb.VDiffResumeRequest) (*vtctldatapb.VDiffResumeResponse, error) { + span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffResume") + defer span.Finish() + + targetShards := req.GetTargetShards() + + span.Annotate("keyspace", req.TargetKeyspace) + span.Annotate("workflow", req.Workflow) + span.Annotate("uuid", req.Uuid) + span.Annotate("target_shards", targetShards) + + tabletreq := &tabletmanagerdatapb.VDiffRequest{ + Keyspace: req.TargetKeyspace, + Workflow: req.Workflow, + Action: string(vdiff.ResumeAction), + VdiffUuid: req.Uuid, + } + + ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) + if err != nil { + return nil, err + } + + if len(targetShards) > 0 { + if err := applyTargetShards(ts, targetShards); err != nil { + return nil, err + } + } + + err = ts.ForAllTargets(func(target *MigrationTarget) error { + _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) + return err + }) + if err != nil { + s.Logger().Errorf("Error executing vdiff resume action: %v", err) + return nil, err + } + + return &vtctldatapb.VDiffResumeResponse{}, nil +} + +// VDiffShow is part of the vtctlservicepb.VtctldServer interface. +func (s *Server) VDiffShow(ctx context.Context, req *vtctldatapb.VDiffShowRequest) (*vtctldatapb.VDiffShowResponse, error) { + span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffShow") + defer span.Finish() + + span.Annotate("keyspace", req.TargetKeyspace) + span.Annotate("workflow", req.Workflow) + span.Annotate("argument", req.Arg) + + tabletreq := &tabletmanagerdatapb.VDiffRequest{ + Keyspace: req.TargetKeyspace, + Workflow: req.Workflow, + Action: string(vdiff.ShowAction), + ActionArg: req.Arg, + } + + ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) + if err != nil { + return nil, err + } + + output := &vdiffOutput{ + responses: make(map[string]*tabletmanagerdatapb.VDiffResponse, len(ts.targets)), + err: nil, + } + output.err = ts.ForAllTargets(func(target *MigrationTarget) error { + resp, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) + output.mu.Lock() + defer output.mu.Unlock() + output.responses[target.GetShard().ShardName()] = resp + return err + }) + if output.err != nil { + s.Logger().Errorf("Error executing vdiff show action: %v", output.err) + return nil, output.err + } + return &vtctldatapb.VDiffShowResponse{ + TabletResponses: output.responses, + }, nil +} + +// VDiffStop is part of the vtctlservicepb.VtctldServer interface. +func (s *Server) VDiffStop(ctx context.Context, req *vtctldatapb.VDiffStopRequest) (*vtctldatapb.VDiffStopResponse, error) { + span, ctx := trace.NewSpan(ctx, "workflow.Server.VDiffStop") + defer span.Finish() + + targetShards := req.GetTargetShards() + + span.Annotate("keyspace", req.TargetKeyspace) + span.Annotate("workflow", req.Workflow) + span.Annotate("uuid", req.Uuid) + span.Annotate("target_shards", targetShards) + + tabletreq := &tabletmanagerdatapb.VDiffRequest{ + Keyspace: req.TargetKeyspace, + Workflow: req.Workflow, + Action: string(vdiff.StopAction), + VdiffUuid: req.Uuid, + } + + ts, err := s.buildTrafficSwitcher(ctx, req.TargetKeyspace, req.Workflow) + if err != nil { + return nil, err + } + + if len(targetShards) > 0 { + if err := applyTargetShards(ts, targetShards); err != nil { + return nil, err + } + } + + err = ts.ForAllTargets(func(target *MigrationTarget) error { + _, err := s.tmc.VDiff(ctx, target.GetPrimary().Tablet, tabletreq) + return err + }) + if err != nil { + s.Logger().Errorf("Error executing vdiff stop action: %v", err) + return nil, err + } + + return &vtctldatapb.VDiffStopResponse{}, nil +} diff --git a/go/vt/vtctl/workflow/vdiff_test.go b/go/vt/vtctl/workflow/vdiff_test.go new file mode 100644 index 00000000000..0da4a3ef480 --- /dev/null +++ b/go/vt/vtctl/workflow/vdiff_test.go @@ -0,0 +1,491 @@ +/* +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" + "math" + "testing" + "time" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vdiff" + + 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" +) + +func TestBuildProgressReport(t *testing.T) { + now := time.Now() + type args struct { + summary *Summary + rowsToCompare int64 + } + tests := []struct { + name string + args args + want *vdiff.ProgressReport + }{ + { + name: "no progress", + args: args{ + summary: &Summary{RowsCompared: 0}, + rowsToCompare: 100, + }, + want: &vdiff.ProgressReport{ + Percentage: 0, + ETA: "", // no ETA + }, + }, + { + name: "one third of the way", + args: args{ + summary: &Summary{ + RowsCompared: 33, + StartedAt: now.Add(-10 * time.Second).UTC().Format(vdiff.TimestampFormat), + }, + rowsToCompare: 100, + }, + want: &vdiff.ProgressReport{ + Percentage: 33, + ETA: now.Add(20 * time.Second).UTC().Format(vdiff.TimestampFormat), + }, + }, + { + name: "half way", + args: args{ + summary: &Summary{ + RowsCompared: 5000000000, + StartedAt: now.Add(-10 * time.Hour).UTC().Format(vdiff.TimestampFormat), + }, + rowsToCompare: 10000000000, + }, + want: &vdiff.ProgressReport{ + Percentage: 50, + ETA: now.Add(10 * time.Hour).UTC().Format(vdiff.TimestampFormat), + }, + }, + { + name: "full progress", + args: args{ + summary: &Summary{ + RowsCompared: 100, + CompletedAt: now.UTC().Format(vdiff.TimestampFormat), + }, + rowsToCompare: 100, + }, + want: &vdiff.ProgressReport{ + Percentage: 100, + ETA: now.UTC().Format(vdiff.TimestampFormat), + }, + }, + { + name: "more than in I_S", + args: args{ + summary: &Summary{ + RowsCompared: 100, + CompletedAt: now.UTC().Format(vdiff.TimestampFormat), + }, + rowsToCompare: 50, + }, + want: &vdiff.ProgressReport{ + Percentage: 100, + ETA: now.UTC().Format(vdiff.TimestampFormat), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.args.summary.Progress = BuildProgressReport(tt.args.summary.RowsCompared, tt.args.rowsToCompare, tt.args.summary.StartedAt) + // We always check the percentage + require.Equal(t, int(tt.want.Percentage), int(tt.args.summary.Progress.Percentage)) + + // We only check the ETA if there is one. + if tt.want.ETA != "" { + // Let's check that we're within 1 second to avoid flakes. + wantTime, err := time.Parse(vdiff.TimestampFormat, tt.want.ETA) + require.NoError(t, err) + var timeDiff float64 + if tt.want.Percentage == 100 { + completedTime, err := time.Parse(vdiff.TimestampFormat, tt.args.summary.CompletedAt) + require.NoError(t, err) + timeDiff = math.Abs(completedTime.Sub(wantTime).Seconds()) + } else { + startTime, err := time.Parse(vdiff.TimestampFormat, tt.args.summary.StartedAt) + require.NoError(t, err) + completedTimeUnix := float64(now.UTC().Unix()-startTime.UTC().Unix()) * (100 / tt.want.Percentage) + estimatedTime, err := time.Parse(vdiff.TimestampFormat, tt.want.ETA) + require.NoError(t, err) + timeDiff = math.Abs(estimatedTime.Sub(startTime).Seconds() - completedTimeUnix) + } + require.LessOrEqual(t, timeDiff, 1.0) + } + }) + } +} + +// TestVDiffCreate performs some basic tests of the VDiffCreate function +// to ensure that it behaves as expected given a specific request. +func TestVDiffCreate(t *testing.T) { + ctx := context.Background() + workflowName := "wf1" + sourceKeyspace := &testKeyspace{ + KeyspaceName: "source", + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: "target", + ShardNames: []string{"-80", "80-"}, + } + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + + tests := []struct { + name string + req *vtctldatapb.VDiffCreateRequest + wantErr string + }{ + { + name: "no values", + req: &vtctldatapb.VDiffCreateRequest{}, + // We did not provide any keyspace or shard. + wantErr: "FindAllShardsInKeyspace() invalid keyspace name: UnescapeID err: invalid input identifier ''", + }, + { + name: "generated UUID", + req: &vtctldatapb.VDiffCreateRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + Workflow: workflowName, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.wantErr == "" { + env.tmc.expectVRQueryResultOnKeyspaceTablets(targetKeyspace.KeyspaceName, &queryResult{ + query: "select vrepl_id, table_name, lastpk from _vt.copy_state where vrepl_id in (1) and id in (select max(id) from _vt.copy_state where vrepl_id in (1) group by vrepl_id, table_name)", + result: &querypb.QueryResult{}, + }) + } + got, err := env.ws.VDiffCreate(ctx, tt.req) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + return + } + require.NoError(t, err) + require.NotNil(t, got) + // Ensure that we always use a valid UUID. + err = uuid.Validate(got.UUID) + require.NoError(t, err) + }) + } +} + +func TestVDiffResume(t *testing.T) { + ctx := context.Background() + sourceKeyspace := &testKeyspace{ + KeyspaceName: "sourceks", + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: "targetks", + ShardNames: []string{"-80", "80-"}, + } + workflow := "testwf" + uuid := uuid.New().String() + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + + env.tmc.strict = true + action := string(vdiff.ResumeAction) + + tests := []struct { + name string + req *vtctldatapb.VDiffResumeRequest // vtctld requests + expectedVDiffRequests map[*topodatapb.Tablet]*vdiffRequestResponse // tablet requests + wantErr string + }{ + { + name: "basic resume", // Both target shards + req: &vtctldatapb.VDiffResumeRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Uuid: uuid, + }, + expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + VdiffUuid: uuid, + }, + }, + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID+tabletUIDStep]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + VdiffUuid: uuid, + }, + }, + }, + }, + { + name: "resume on first shard", + req: &vtctldatapb.VDiffResumeRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + TargetShards: targetKeyspace.ShardNames[:1], + Workflow: workflow, + Uuid: uuid, + }, + expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + VdiffUuid: uuid, + }, + }, + }, + }, + { + name: "resume on invalid shard", + req: &vtctldatapb.VDiffResumeRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + TargetShards: []string{"0"}, + Workflow: workflow, + Uuid: uuid, + }, + wantErr: fmt.Sprintf("specified target shard 0 not a valid target for workflow %s", workflow), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for tab, vdr := range tt.expectedVDiffRequests { + env.tmc.expectVDiffRequest(tab, vdr) + } + got, err := env.ws.VDiffResume(ctx, tt.req) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + require.NotNil(t, got) + } + env.tmc.confirmVDiffRequests(t) + }) + } +} + +func TestVDiffStop(t *testing.T) { + ctx := context.Background() + sourceKeyspace := &testKeyspace{ + KeyspaceName: "sourceks", + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: "targetks", + ShardNames: []string{"-80", "80-"}, + } + workflow := "testwf" + uuid := uuid.New().String() + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + + env.tmc.strict = true + action := string(vdiff.StopAction) + + tests := []struct { + name string + req *vtctldatapb.VDiffStopRequest // vtctld requests + expectedVDiffRequests map[*topodatapb.Tablet]*vdiffRequestResponse // tablet requests + wantErr string + }{ + { + name: "basic stop", // Both target shards + req: &vtctldatapb.VDiffStopRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Uuid: uuid, + }, + expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + VdiffUuid: uuid, + }, + }, + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID+tabletUIDStep]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + VdiffUuid: uuid, + }, + }, + }, + }, + { + name: "stop on first shard", + req: &vtctldatapb.VDiffStopRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + TargetShards: targetKeyspace.ShardNames[:1], + Workflow: workflow, + Uuid: uuid, + }, + expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + VdiffUuid: uuid, + }, + }, + }, + }, + { + name: "stop on invalid shard", + req: &vtctldatapb.VDiffStopRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + TargetShards: []string{"0"}, + Workflow: workflow, + Uuid: uuid, + }, + wantErr: fmt.Sprintf("specified target shard 0 not a valid target for workflow %s", workflow), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for tab, vdr := range tt.expectedVDiffRequests { + env.tmc.expectVDiffRequest(tab, vdr) + } + got, err := env.ws.VDiffStop(ctx, tt.req) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + require.NotNil(t, got) + } + env.tmc.confirmVDiffRequests(t) + }) + } +} + +func TestVDiffDelete(t *testing.T) { + ctx := context.Background() + sourceKeyspace := &testKeyspace{ + KeyspaceName: "sourceks", + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: "targetks", + ShardNames: []string{"-80", "80-"}, + } + workflow := "testwf" + uuid := uuid.New().String() + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + + env.tmc.strict = true + action := string(vdiff.DeleteAction) + + tests := []struct { + name string + req *vtctldatapb.VDiffDeleteRequest + expectedVDiffRequests map[*topodatapb.Tablet]*vdiffRequestResponse + wantErr string + }{ + { + name: "basic delete", + req: &vtctldatapb.VDiffDeleteRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Arg: uuid, + }, + expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + ActionArg: uuid, + }, + }, + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID+tabletUIDStep]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + ActionArg: uuid, + }, + }, + }, + }, + { + name: "invalid delete", + req: &vtctldatapb.VDiffDeleteRequest{ + TargetKeyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Arg: uuid, + }, + expectedVDiffRequests: map[*topodatapb.Tablet]*vdiffRequestResponse{ + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + ActionArg: uuid, + }, + err: fmt.Errorf("error on invalid delete"), + }, + env.tablets[targetKeyspace.KeyspaceName][startingTargetTabletUID+tabletUIDStep]: { + req: &tabletmanagerdatapb.VDiffRequest{ + Keyspace: targetKeyspace.KeyspaceName, + Workflow: workflow, + Action: action, + ActionArg: uuid, + }, + }, + }, + wantErr: "error on invalid delete", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for tab, vdr := range tt.expectedVDiffRequests { + env.tmc.expectVDiffRequest(tab, vdr) + } + got, err := env.ws.VDiffDelete(ctx, tt.req) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + require.NotNil(t, got) + } + env.tmc.confirmVDiffRequests(t) + }) + } +} diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index d8ac8beccc1..2809c37540d 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -28,7 +28,9 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/servenv/testutils" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/wrangler" @@ -53,7 +55,7 @@ func TestAPI(t *testing.T) { defer server.Close() ks1 := &topodatapb.Keyspace{ - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, SidecarDbName: "_vt_sidecar_ks1", } @@ -81,7 +83,10 @@ func TestAPI(t *testing.T) { }, }, } - ts.SaveVSchema(ctx, "ks1", vs) + ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks1", + Keyspace: vs, + }) tablet1 := topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "cell1", Uid: 100}, diff --git a/go/vt/vterrors/code.go b/go/vt/vterrors/code.go index 31c98cef280..df19fcbd408 100644 --- a/go/vt/vterrors/code.go +++ b/go/vt/vterrors/code.go @@ -102,6 +102,7 @@ var ( VT09028 = errorWithState("VT09028", vtrpcpb.Code_FAILED_PRECONDITION, CTERecursiveForbiddenJoinOrder, "In recursive query block of Recursive Common Table Expression '%s', the recursive table must neither be in the right argument of a LEFT JOIN, nor be forced to be non-first with join order hints", "") VT09029 = errorWithState("VT09029", vtrpcpb.Code_FAILED_PRECONDITION, CTERecursiveRequiresSingleReference, "In recursive query block of Recursive Common Table Expression %s, the recursive table must be referenced only once, and not in any subquery", "") VT09030 = errorWithState("VT09030", vtrpcpb.Code_FAILED_PRECONDITION, CTEMaxRecursionDepth, "Recursive query aborted after 1000 iterations.", "") + VT09031 = errorWithoutState("VT09031", vtrpcpb.Code_FAILED_PRECONDITION, "Primary demotion is stalled", "") VT10001 = errorWithoutState("VT10001", vtrpcpb.Code_ABORTED, "foreign key constraints are not allowed", "Foreign key constraints are not allowed, see https://vitess.io/blog/2021-06-15-online-ddl-why-no-fk/.") VT10002 = errorWithoutState("VT10002", vtrpcpb.Code_ABORTED, "atomic distributed transaction not allowed: %s", "The distributed transaction cannot be committed. A rollback decision is taken.") @@ -192,6 +193,8 @@ var ( VT09027, VT09028, VT09029, + VT09030, + VT09031, VT10001, VT10002, VT12001, @@ -240,8 +243,15 @@ func errorWithoutState(id string, code vtrpcpb.Code, short, long string) func(ar func errorWithState(id string, code vtrpcpb.Code, state State, short, long string) func(args ...any) *VitessError { return func(args ...any) *VitessError { + var err error + if len(args) != 0 { + err = NewErrorf(code, state, id+": "+short, args...) + } else { + err = NewError(code, state, id+": "+short) + } + return &VitessError{ - Err: NewErrorf(code, state, id+": "+short, args...), + Err: err, Description: long, ID: id, State: state, diff --git a/go/vt/vtexplain/vtexplain_vtgate.go b/go/vt/vtexplain/vtexplain_vtgate.go index f9ae8be3820..155fe6de743 100644 --- a/go/vt/vtexplain/vtexplain_vtgate.go +++ b/go/vt/vtexplain/vtexplain_vtgate.go @@ -74,7 +74,12 @@ func (vte *VTExplain) initVtgateExecutor(ctx context.Context, ts *topo.Server, v var schemaTracker vtgate.SchemaInfo // no schema tracker for these tests queryLogBufferSize := 10 plans := theine.NewStore[vtgate.PlanCacheKey, *engine.Plan](4*1024*1024, false) - vte.vtgateExecutor = vtgate.NewExecutor(ctx, vte.env, vte.explainTopo, Cell, resolver, opts.Normalize, false, streamSize, plans, schemaTracker, false, opts.PlannerVersion, 0) + eConfig := vtgate.ExecutorConfig{ + Normalize: opts.Normalize, + StreamSize: streamSize, + AllowScatter: true, + } + vte.vtgateExecutor = vtgate.NewExecutor(ctx, vte.env, vte.explainTopo, Cell, resolver, eConfig, false, plans, schemaTracker, opts.PlannerVersion, vtgate.NewDynamicViperConfig()) vte.vtgateExecutor.SetQueryLogger(streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize)) return nil @@ -88,7 +93,9 @@ func (vte *VTExplain) newFakeResolver(ctx context.Context, opts *Options, serv s if opts.ExecutionMode == ModeTwoPC { txMode = vtgatepb.TransactionMode_TWOPC } - tc := vtgate.NewTxConn(gw, txMode) + tc := vtgate.NewTxConn(gw, &vtgate.StaticConfig{ + TxMode: txMode, + }) sc := vtgate.NewScatterConn("", tc, gw) srvResolver := srvtopo.NewResolver(serv, gw, cell) return vtgate.NewResolver(srvResolver, serv, cell, sc) diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index 38a3ca7bbb3..94697c22e91 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -22,6 +22,7 @@ import ( "reflect" "strings" "sync" + "time" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/sidecardb" @@ -113,8 +114,7 @@ func (vte *VTExplain) newTablet(ctx context.Context, env *vtenv.Environment, opt config := tabletenv.NewCurrentConfig() config.TrackSchemaVersions = false if opts.ExecutionMode == ModeTwoPC { - config.TwoPCAbandonAge = 1.0 - config.TwoPCEnable = true + config.TwoPCAbandonAge = 1 * time.Second } config.EnableOnlineDDL = false config.EnableTableGC = false @@ -621,7 +621,10 @@ func (t *explainTablet) handleSelect(query string) (*sqltypes.Result, error) { case *sqlparser.Select: selStmt = stmt case *sqlparser.Union: - selStmt = sqlparser.GetFirstSelect(stmt) + selStmt, err = sqlparser.GetFirstSelect(stmt) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("vtexplain: unsupported statement type +%v", reflect.TypeOf(stmt)) } diff --git a/go/vt/vtgate/bench_test.go b/go/vt/vtgate/bench_test.go index 5c64c7e3473..c2336662c69 100644 --- a/go/vt/vtgate/bench_test.go +++ b/go/vt/vtgate/bench_test.go @@ -80,7 +80,7 @@ func BenchmarkWithNormalizer(b *testing.B) { func BenchmarkWithoutNormalizer(b *testing.B) { vtgateInst, _, ctx := createVtgateEnv(b) - vtgateInst.executor.normalize = false + vtgateInst.executor.config.Normalize = false for i := 0; i < b.N; i++ { _, _, err := vtgateInst.Execute( diff --git a/go/vt/vtgate/dynamicconfig/config.go b/go/vt/vtgate/dynamicconfig/config.go index 5bb1d991eae..014160029cd 100644 --- a/go/vt/vtgate/dynamicconfig/config.go +++ b/go/vt/vtgate/dynamicconfig/config.go @@ -1,6 +1,28 @@ +/* +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 dynamicconfig +import vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + type DDL interface { OnlineEnabled() bool DirectEnabled() bool } + +type TxMode interface { + TransactionMode() vtgatepb.TransactionMode +} diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index c764a6aab08..50d3a4b6bbf 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -546,7 +546,7 @@ func (cached *InsertSelect) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(176) + size += int64(192) } // field InsertCommon vitess.io/vitess/go/vt/vtgate/engine.InsertCommon size += cached.InsertCommon.CachedSize(false) @@ -609,7 +609,7 @@ func (cached *Limit) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(48) + size += int64(64) } // field Count vitess.io/vitess/go/vt/vtgate/evalengine.Expr if cc, ok := cached.Count.(cachedObject); ok { diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 7783e6bdc12..152894d5eab 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -145,7 +145,7 @@ func (c *DBDDL) createDatabase(ctx context.Context, vcursor VCursor, plugin DBDD } for { - _, errors := vcursor.ExecuteMultiShard(ctx, c, destinations, queries, false, true) + _, errors := vcursor.ExecuteMultiShard(ctx, c, destinations, queries, false, true, false) noErr := true for _, err := range errors { diff --git a/go/vt/vtgate/engine/delete.go b/go/vt/vtgate/engine/delete.go index 91bcca5cf6a..14859fc2135 100644 --- a/go/vt/vtgate/engine/delete.go +++ b/go/vt/vtgate/engine/delete.go @@ -87,7 +87,7 @@ func (del *Delete) deleteVindexEntries(ctx context.Context, vcursor VCursor, bin for i := range rss { queries[i] = &querypb.BoundQuery{Sql: del.OwnedVindexQuery, BindVariables: bindVars} } - subQueryResults, errors := vcursor.ExecuteMultiShard(ctx, del, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + subQueryResults, errors := vcursor.ExecuteMultiShard(ctx, del, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, del.FetchLastInsertID) for _, err := range errors { if err != nil { return err @@ -131,6 +131,9 @@ func (del *Delete) description() PrimitiveDescription { } addFieldsIfNotEmpty(del.DML, other) + if del.FetchLastInsertID { + other["FetchLastInsertID"] = del.FetchLastInsertID + } return PrimitiveDescription{ OperatorType: "Delete", diff --git a/go/vt/vtgate/engine/dml.go b/go/vt/vtgate/engine/dml.go index db777c36698..9a0a044a3c4 100644 --- a/go/vt/vtgate/engine/dml.go +++ b/go/vt/vtgate/engine/dml.go @@ -65,6 +65,8 @@ type DML struct { PreventAutoCommit bool + FetchLastInsertID bool + // RoutingParameters parameters required for query routing. *RoutingParameters } @@ -75,7 +77,7 @@ func NewDML() *DML { } func (dml *DML) execUnsharded(ctx context.Context, primitive Primitive, vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard) (*sqltypes.Result, error) { - return execShard(ctx, primitive, vcursor, dml.Query, bindVars, rss[0], true /* rollbackOnError */, !dml.PreventAutoCommit /* canAutocommit */) + return execShard(ctx, primitive, vcursor, dml.Query, bindVars, rss[0], true /* rollbackOnError */, !dml.PreventAutoCommit /* canAutocommit */, dml.FetchLastInsertID) } func (dml *DML) execMultiDestination(ctx context.Context, primitive Primitive, vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard, dmlSpecialFunc func(context.Context, VCursor, @@ -94,7 +96,7 @@ func (dml *DML) execMultiDestination(ctx context.Context, primitive Primitive, v BindVariables: bvs[i], } } - return execMultiShard(ctx, primitive, vcursor, rss, queries, dml.MultiShardAutocommit) + return dml.execMultiShard(ctx, primitive, vcursor, rss, queries) } // RouteType returns a description of the query routing type used by the primitive @@ -130,9 +132,9 @@ func allowOnlyPrimary(rss ...*srvtopo.ResolvedShard) error { return nil } -func execMultiShard(ctx context.Context, primitive Primitive, vcursor VCursor, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, multiShardAutoCommit bool) (*sqltypes.Result, error) { - autocommit := (len(rss) == 1 || multiShardAutoCommit) && vcursor.AutocommitApproval() - result, errs := vcursor.ExecuteMultiShard(ctx, primitive, rss, queries, true /* rollbackOnError */, autocommit) +func (dml *DML) execMultiShard(ctx context.Context, primitive Primitive, vcursor VCursor, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery) (*sqltypes.Result, error) { + autocommit := (len(rss) == 1 || dml.MultiShardAutocommit) && vcursor.AutocommitApproval() + result, errs := vcursor.ExecuteMultiShard(ctx, primitive, rss, queries, true /*rollbackOnError*/, autocommit, dml.FetchLastInsertID) return result, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/fake_primitive_test.go b/go/vt/vtgate/engine/fake_primitive_test.go index b878c1931c0..f3ab5ad5336 100644 --- a/go/vt/vtgate/engine/fake_primitive_test.go +++ b/go/vt/vtgate/engine/fake_primitive_test.go @@ -40,7 +40,8 @@ type fakePrimitive struct { // sendErr is sent at the end of the stream if it's set. sendErr error - log []string + noLog bool + log []string allResultsInOneCall bool @@ -85,7 +86,9 @@ func (f *fakePrimitive) TryExecute(ctx context.Context, vcursor VCursor, bindVar } func (f *fakePrimitive) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - f.log = append(f.log, fmt.Sprintf("StreamExecute %v %v", printBindVars(bindVars), wantfields)) + if !f.noLog { + f.log = append(f.log, fmt.Sprintf("StreamExecute %v %v", printBindVars(bindVars), wantfields)) + } if f.results == nil { return f.sendErr } diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 9ba4fdc6a6b..060d2ebcfcb 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -164,7 +164,7 @@ func (t *noopVCursor) Environment() *vtenv.Environment { } func (t *noopVCursor) TimeZone() *time.Location { - return nil + return time.Local } func (t *noopVCursor) SQLMode() string { @@ -368,7 +368,7 @@ func (t *noopVCursor) Execute(ctx context.Context, method string, query string, panic("unimplemented") } -func (t *noopVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { +func (t *noopVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) { panic("unimplemented") } @@ -376,11 +376,11 @@ func (t *noopVCursor) AutocommitApproval() bool { panic("unimplemented") } -func (t *noopVCursor) ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { +func (t *noopVCursor) ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) { panic("unimplemented") } -func (t *noopVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error { +func (t *noopVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error { panic("unimplemented") } @@ -400,6 +400,20 @@ func (t *noopVCursor) GetDBDDLPluginName() string { panic("unimplemented") } +func (t *noopVCursor) SetLastInsertID(uint64) {} +func (t *noopVCursor) VExplainLogging() {} +func (t *noopVCursor) DisableLogging() {} +func (t *noopVCursor) GetVExplainLogs() []ExecuteEntry { + return nil +} +func (t *noopVCursor) GetLogs() ([]ExecuteEntry, error) { + return nil, nil +} + +// RecordMirrorStats implements VCursor. +func (t *noopVCursor) RecordMirrorStats(sourceExecTime, targetExecTime time.Duration, targetErr error) { +} + var ( _ VCursor = (*loggingVCursor)(nil) _ SessionActions = (*loggingVCursor)(nil) @@ -587,7 +601,7 @@ func (f *loggingVCursor) Execute(ctx context.Context, method string, query strin return f.nextResult() } -func (f *loggingVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { +func (f *loggingVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) { f.mu.Lock() defer f.mu.Unlock() f.log = append(f.log, fmt.Sprintf("ExecuteMultiShard %v%v %v", printResolvedShardQueries(rss, queries), rollbackOnError, canAutocommit)) @@ -606,12 +620,12 @@ func (f *loggingVCursor) AutocommitApproval() bool { return true } -func (f *loggingVCursor) ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { +func (f *loggingVCursor) ExecuteStandalone(ctx context.Context, _ Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) { f.log = append(f.log, fmt.Sprintf("ExecuteStandalone %s %v %s %s", query, printBindVars(bindvars), rs.Target.Keyspace, rs.Target.Shard)) return f.nextResult() } -func (f *loggingVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error { +func (f *loggingVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error { f.mu.Lock() f.log = append(f.log, fmt.Sprintf("StreamExecuteMulti %s %s", query, printResolvedShardsBindVars(rss, bindVars))) if f.onStreamExecuteMultiFn != nil { @@ -893,20 +907,6 @@ func (t *loggingVCursor) RecordMirrorStats(sourceExecTime, targetExecTime time.D } } -func (t *noopVCursor) VExplainLogging() {} -func (t *noopVCursor) DisableLogging() {} -func (t *noopVCursor) GetVExplainLogs() []ExecuteEntry { - return nil -} - -func (t *noopVCursor) GetLogs() ([]ExecuteEntry, error) { - return nil, nil -} - -// RecordMirrorStats implements VCursor. -func (t *noopVCursor) RecordMirrorStats(sourceExecTime, targetExecTime time.Duration, targetErr error) { -} - func expectResult(t *testing.T, result, want *sqltypes.Result) { t.Helper() fieldsResult := fmt.Sprintf("%v", result.Fields) diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index cd462966ccc..5bc206f7465 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -60,7 +60,7 @@ type Insert struct { Alias string } -// newQueryInsert creates an Insert with a query string. +// newQueryInsert creates an Insert with a query string. Used in testing. func newQueryInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, query string) *Insert { return &Insert{ InsertCommon: InsertCommon{ @@ -71,7 +71,7 @@ func newQueryInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, query stri } } -// newInsert creates a new Insert. +// newInsert creates a new Insert. Used in testing. func newInsert( opcode InsertOpcode, ignore bool, @@ -169,13 +169,14 @@ func (ins *Insert) executeInsertQueries( if err != nil { return nil, err } - result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true /* rollbackOnError */, autocommit) + result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true /*rollbackOnError*/, autocommit, ins.FetchLastInsertID) if errs != nil { return nil, vterrors.Aggregate(errs) } if insertID != 0 { result.InsertID = insertID + result.InsertIDChanged = true } return result, nil } @@ -383,6 +384,10 @@ func (ins *Insert) description() PrimitiveDescription { } } + if ins.FetchLastInsertID { + other["FetchLastInsertID"] = true + } + return PrimitiveDescription{ OperatorType: "Insert", Keyspace: ins.Keyspace, diff --git a/go/vt/vtgate/engine/insert_common.go b/go/vt/vtgate/engine/insert_common.go index e29aa7fd792..d4cae045e86 100644 --- a/go/vt/vtgate/engine/insert_common.go +++ b/go/vt/vtgate/engine/insert_common.go @@ -77,6 +77,8 @@ type ( // ColVindexes are the vindexes that will use the VindexValues ColVindexes []*vindexes.ColumnVindex + FetchLastInsertID bool + // Prefix, Suffix are for sharded insert plans. Prefix string Suffix sqlparser.OnDup @@ -159,7 +161,7 @@ func (ins *InsertCommon) executeUnshardedTableQuery(ctx context.Context, vcursor if err != nil { return nil, err } - qr, err := execShard(ctx, loggingPrimitive, vcursor, query, bindVars, rss[0], true, !ins.PreventAutoCommit /* canAutocommit */) + qr, err := execShard(ctx, loggingPrimitive, vcursor, query, bindVars, rss[0], true, !ins.PreventAutoCommit /* canAutocommit */, ins.FetchLastInsertID) if err != nil { return nil, err } @@ -169,6 +171,7 @@ func (ins *InsertCommon) executeUnshardedTableQuery(ctx context.Context, vcursor // values, we don't return an error because this behavior // is required to support migration. if insertID != 0 { + qr.InsertIDChanged = true qr.InsertID = insertID } return qr, nil @@ -451,7 +454,7 @@ func (ic *InsertCommon) execGenerate(ctx context.Context, vcursor VCursor, loggi return 0, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "auto sequence generation can happen through single shard only, it is getting routed to %d shards", len(rss)) } bindVars := map[string]*querypb.BindVariable{nextValBV: sqltypes.Int64BindVariable(count)} - qr, err := vcursor.ExecuteStandalone(ctx, loggingPrimitive, ic.Generate.Query, bindVars, rss[0]) + qr, err := vcursor.ExecuteStandalone(ctx, loggingPrimitive, ic.Generate.Query, bindVars, rss[0], ic.FetchLastInsertID) if err != nil { return 0, err } diff --git a/go/vt/vtgate/engine/insert_select.go b/go/vt/vtgate/engine/insert_select.go index f8f3936e323..af834858175 100644 --- a/go/vt/vtgate/engine/insert_select.go +++ b/go/vt/vtgate/engine/insert_select.go @@ -51,7 +51,7 @@ type ( } ) -// newInsertSelect creates a new InsertSelect. +// newInsertSelect creates a new InsertSelect. Used in testing. func newInsertSelect( ignore bool, keyspace *vindexes.Keyspace, @@ -207,7 +207,7 @@ func (ins *InsertSelect) executeInsertQueries( if err != nil { return nil, err } - result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true /* rollbackOnError */, autocommit) + result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true, autocommit, false) if errs != nil { return nil, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/limit.go b/go/vt/vtgate/engine/limit.go index 01fcde6bd82..d50a0d4adde 100644 --- a/go/vt/vtgate/engine/limit.go +++ b/go/vt/vtgate/engine/limit.go @@ -33,11 +33,22 @@ import ( var _ Primitive = (*Limit)(nil) -// Limit is a primitive that performs the LIMIT operation. +// Limit performs the LIMIT operation, restricting the number of rows returned. type Limit struct { - Count evalengine.Expr + // Count specifies the maximum number of rows to return. + Count evalengine.Expr + + // Offset specifies the number of rows to skip before returning results. Offset evalengine.Expr - Input Primitive + + // RequireCompleteInput determines if all input rows must be fully retrieved. + // - If true, all Result structs are passed through, and the total rows are limited. + // - If false, Limit returns io.EOF once the limit is reached in streaming mode, + // signaling the tablet to stop sending data. + RequireCompleteInput bool + + // Input provides the input rows. + Input Primitive } var UpperLimitStr = "__upper_limit" @@ -88,6 +99,10 @@ func (l *Limit) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[st return result, nil } +func (l *Limit) mustRetrieveAll(vcursor VCursor) bool { + return l.RequireCompleteInput || vcursor.Session().InTransaction() +} + // TryStreamExecute satisfies the Primitive interface. func (l *Limit) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { count, offset, err := l.getCountAndOffset(ctx, vcursor, bindVars) @@ -97,57 +112,78 @@ func (l *Limit) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars bindVars = copyBindVars(bindVars) - // When offset is present, we hijack the limit value so we can calculate - // the offset in memory from the result of the scatter query with count + offset. + // Adjust the upper limit so that the initial fetch includes both the offset and count. + // We do this because we want to skip the first `offset` rows locally rather than on the server side. bindVars[UpperLimitStr] = sqltypes.Int64BindVariable(int64(count + offset)) var mu sync.Mutex err = vcursor.StreamExecutePrimitive(ctx, l.Input, bindVars, wantfields, func(qr *sqltypes.Result) error { mu.Lock() defer mu.Unlock() - if wantfields && len(qr.Fields) != 0 { - if err := callback(&sqltypes.Result{Fields: qr.Fields}); err != nil { - return err - } - } - inputSize := len(qr.Rows) - if inputSize == 0 { - return nil - } - // we've still not seen all rows we need to see before we can return anything to the client + inputSize := len(qr.Rows) + // If we still need to skip `offset` rows before returning any to the client: if offset > 0 { if inputSize <= offset { - // not enough to return anything yet + // not enough to return anything yet, but we still want to pass on metadata such as last_insert_id offset -= inputSize - return nil + if !wantfields && !l.mustRetrieveAll(vcursor) { + return nil + } + if len(qr.Fields) > 0 { + wantfields = false + } + qr.Rows = nil + return callback(qr) } + // Skip `offset` rows from this batch and reset offset to 0. qr.Rows = qr.Rows[offset:] offset = 0 } + // At this point, we've dealt with the offset. Now handle the count (limit). if count == 0 { - return io.EOF + // If count is zero, we've fetched everything we need. + if !wantfields && !l.mustRetrieveAll(vcursor) { + return io.EOF + } + if len(qr.Fields) > 0 { + wantfields = false + } + + // If we require the complete input, or we are in a transaction, we cannot return io.EOF early. + // Instead, we return empty results as needed until input ends. + qr.Rows = nil + return callback(qr) + } + + if len(qr.Fields) > 0 { + wantfields = false } // reduce count till 0. - result := &sqltypes.Result{Rows: qr.Rows} - resultSize := len(result.Rows) + resultSize := len(qr.Rows) if count > resultSize { count -= resultSize - return callback(result) + return callback(qr) } - result.Rows = result.Rows[:count] + + qr.Rows = qr.Rows[:count] count = 0 - if err := callback(result); err != nil { + if err := callback(qr); err != nil { return err } + + // If we required complete input or are in a transaction, we must not exit early. + // We'll return empty batches until the input is done. + if l.mustRetrieveAll(vcursor) { + return nil + } + return io.EOF }) if err == io.EOF { - // We may get back the EOF we returned in the callback. - // If so, suppress it. return nil } if err != nil { @@ -217,6 +253,9 @@ func (l *Limit) description() PrimitiveDescription { if l.Offset != nil { other["Offset"] = sqlparser.String(l.Offset) } + if l.RequireCompleteInput { + other["RequireCompleteInput"] = true + } return PrimitiveDescription{ OperatorType: "Limit", diff --git a/go/vt/vtgate/engine/limit_test.go b/go/vt/vtgate/engine/limit_test.go index 8b91dadecb5..8ab31610e62 100644 --- a/go/vt/vtgate/engine/limit_test.go +++ b/go/vt/vtgate/engine/limit_test.go @@ -353,9 +353,7 @@ func TestLimitOffsetExecute(t *testing.T) { t.Errorf("l.Execute:\n got %v, want\n%v", result, wantResult) } } - func TestLimitStreamExecute(t *testing.T) { - bindVars := make(map[string]*querypb.BindVariable) fields := sqltypes.MakeTestFields( "col1|col2", "int64|varchar", @@ -366,88 +364,88 @@ func TestLimitStreamExecute(t *testing.T) { "b|2", "c|3", ) - fp := &fakePrimitive{ - results: []*sqltypes.Result{inputResult}, - } - - l := &Limit{ - Count: evalengine.NewLiteralInt(2), - Input: fp, - } - // Test with limit smaller than input. - var results []*sqltypes.Result - err := l.TryStreamExecute(context.Background(), &noopVCursor{}, bindVars, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - wantResults := sqltypes.MakeTestStreamingResults( - fields, - "a|1", - "b|2", - ) - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } - } + tests := []struct { + name string + countExpr evalengine.Expr + bindVars map[string]*querypb.BindVariable + want []*sqltypes.Result + RequireCompleteInput bool + }{{ + name: "limit smaller than input (literal)", + countExpr: evalengine.NewLiteralInt(2), + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + ), + }, { + name: "limit smaller than input (literal) - require complete input", + countExpr: evalengine.NewLiteralInt(2), + RequireCompleteInput: true, + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + "---", // this extra result is required by RequireCompleteInput + ), + }, { + name: "limit smaller than input (bind var)", + countExpr: evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)), + bindVars: map[string]*querypb.BindVariable{"l": sqltypes.Int64BindVariable(2)}, + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + ), + }, { + name: "limit equal to input", + countExpr: evalengine.NewLiteralInt(3), + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + "---", + "c|3", + ), + }, { + name: "limit higher than input", + countExpr: evalengine.NewLiteralInt(4), + // same as limit=3 + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + "---", + "c|3", + ), + }} - // Test with bind vars. - fp.rewind() - l.Count = evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) - results = nil - err = l.TryStreamExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{"l": sqltypes.Int64BindVariable(2)}, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fp := &fakePrimitive{ + results: []*sqltypes.Result{inputResult}, + } - // Test with limit equal to input - fp.rewind() - l.Count = evalengine.NewLiteralInt(3) - results = nil - err = l.TryStreamExecute(context.Background(), &noopVCursor{}, bindVars, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - wantResults = sqltypes.MakeTestStreamingResults( - fields, - "a|1", - "b|2", - "---", - "c|3", - ) - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } - } + l := &Limit{ + Count: tt.countExpr, + RequireCompleteInput: tt.RequireCompleteInput, + Input: fp, + } - // Test with limit higher than input. - fp.rewind() - l.Count = evalengine.NewLiteralInt(4) - results = nil - err = l.TryStreamExecute(context.Background(), &noopVCursor{}, bindVars, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - // wantResults is same as before. - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } + var results []*sqltypes.Result + err := l.TryStreamExecute(context.Background(), &noopVCursor{}, tt.bindVars, true, func(qr *sqltypes.Result) error { + results = append(results, qr) + return nil + }) + require.NoError(t, err) + require.Len(t, results, len(tt.want)) + for i, result := range results { + if !result.Equal(tt.want[i]) { + t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(tt.want)) + } + } + }) } } diff --git a/go/vt/vtgate/engine/lock.go b/go/vt/vtgate/engine/lock.go index 7739cbcd0cc..a8ba9f46df3 100644 --- a/go/vt/vtgate/engine/lock.go +++ b/go/vt/vtgate/engine/lock.go @@ -173,7 +173,7 @@ func (l *Lock) GetFields(ctx context.Context, vcursor VCursor, bindVars map[stri Sql: l.FieldQuery, BindVariables: bindVars, }} - qr, errs := vcursor.ExecuteMultiShard(ctx, l, rss, boundQuery, false, true) + qr, errs := vcursor.ExecuteMultiShard(ctx, l, rss, boundQuery, false, true, false) if len(errs) > 0 { return nil, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/merge_sort.go b/go/vt/vtgate/engine/merge_sort.go index fac57c37ccb..abf2a65f311 100644 --- a/go/vt/vtgate/engine/merge_sort.go +++ b/go/vt/vtgate/engine/merge_sort.go @@ -21,19 +21,17 @@ import ( "io" "vitess.io/vitess/go/mysql/sqlerror" - "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" ) // StreamExecutor is a subset of Primitive that MergeSort // requires its inputs to satisfy. type StreamExecutor interface { - StreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error + StreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, fetchLastInsertID bool, callback func(*sqltypes.Result) error) error } var _ Primitive = (*MergeSort)(nil) @@ -54,6 +52,7 @@ type MergeSort struct { Primitives []StreamExecutor OrderBy evalengine.Comparison ScatterErrorsAsWarnings bool + FetchLastInsertID bool } // RouteType satisfies Primitive. @@ -85,7 +84,7 @@ func (ms *MergeSort) TryStreamExecute(ctx context.Context, vcursor VCursor, bind gotFields := wantfields handles := make([]*streamHandle, len(ms.Primitives)) for i, input := range ms.Primitives { - handles[i] = runOneStream(ctx, vcursor, input, bindVars, gotFields) + handles[i] = runOneStream(ctx, vcursor, input, bindVars, gotFields, ms.FetchLastInsertID) if !ms.ScatterErrorsAsWarnings { // we only need the fields from the first input, unless we allow ScatterErrorsAsWarnings. // in that case, we need to ask all the inputs for fields - we don't know which will return anything @@ -216,13 +215,20 @@ func (ms *MergeSort) description() PrimitiveDescription { // routine that pulls the rows out of each streamHandle can abort the stream // by calling canceling the context. type streamHandle struct { - fields chan []*querypb.Field - row chan []sqltypes.Value - err error + fields chan []*querypb.Field + fieldSeen bool + row chan []sqltypes.Value + err error } // runOnestream starts a streaming query on one shard, and returns a streamHandle for it. -func runOneStream(ctx context.Context, vcursor VCursor, input StreamExecutor, bindVars map[string]*querypb.BindVariable, wantfields bool) *streamHandle { +func runOneStream( + ctx context.Context, + vcursor VCursor, + input StreamExecutor, + bindVars map[string]*querypb.BindVariable, + wantfields, fetchLastInsertID bool, +) *streamHandle { handle := &streamHandle{ fields: make(chan []*querypb.Field, 1), row: make(chan []sqltypes.Value, 10), @@ -232,8 +238,9 @@ func runOneStream(ctx context.Context, vcursor VCursor, input StreamExecutor, bi defer close(handle.fields) defer close(handle.row) - handle.err = input.StreamExecute(ctx, vcursor, bindVars, wantfields, func(qr *sqltypes.Result) error { - if len(qr.Fields) != 0 { + handle.err = input.StreamExecute(ctx, vcursor, bindVars, wantfields, fetchLastInsertID, func(qr *sqltypes.Result) error { + if !handle.fieldSeen && len(qr.Fields) != 0 { + handle.fieldSeen = true select { case handle.fields <- qr.Fields: case <-ctx.Done(): diff --git a/go/vt/vtgate/engine/merge_sort_test.go b/go/vt/vtgate/engine/merge_sort_test.go index 6b383e12572..60890283f89 100644 --- a/go/vt/vtgate/engine/merge_sort_test.go +++ b/go/vt/vtgate/engine/merge_sort_test.go @@ -411,7 +411,7 @@ type shardResult struct { sendErr error } -func (sr *shardResult) StreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (sr *shardResult) StreamExecute(_ context.Context, _ VCursor, _ map[string]*querypb.BindVariable, _ bool, _ bool, callback func(*sqltypes.Result) error) error { for _, r := range sr.results { if err := callback(r); err != nil { return err diff --git a/go/vt/vtgate/engine/plan_description.go b/go/vt/vtgate/engine/plan_description.go index dfcad4e5e6b..f19be96123e 100644 --- a/go/vt/vtgate/engine/plan_description.go +++ b/go/vt/vtgate/engine/plan_description.go @@ -126,6 +126,137 @@ func (pd PrimitiveDescription) MarshalJSON() ([]byte, error) { return buf.Bytes(), nil } +// PrimitiveDescriptionFromString creates primitive description out of a data string. +func PrimitiveDescriptionFromString(data string) (pd PrimitiveDescription, err error) { + resultMap := make(map[string]any) + err = json.Unmarshal([]byte(data), &resultMap) + if err != nil { + return PrimitiveDescription{}, err + } + return PrimitiveDescriptionFromMap(resultMap) +} + +// PrimitiveDescriptionFromMap populates the fields of a PrimitiveDescription from a map representation. +func PrimitiveDescriptionFromMap(data map[string]any) (pd PrimitiveDescription, err error) { + if opType, isPresent := data["OperatorType"]; isPresent { + pd.OperatorType = opType.(string) + } + if variant, isPresent := data["Variant"]; isPresent { + pd.Variant = variant.(string) + } + if ksMap, isPresent := data["Keyspace"]; isPresent { + ksMap := ksMap.(map[string]any) + pd.Keyspace = &vindexes.Keyspace{ + Name: ksMap["Name"].(string), + Sharded: ksMap["Sharded"].(bool), + } + } + if ttt, isPresent := data["TargetTabletType"]; isPresent { + val, ok := topodatapb.TabletType_value[ttt.(string)] + if !ok { + panic(fmt.Sprintf("TargetTabletType is not a valid tablet type: %v", ttt)) + } + pd.TargetTabletType = topodatapb.TabletType(val) + } + if other, isPresent := data["Other"]; isPresent { + pd.Other = other.(map[string]any) + } + if inpName, isPresent := data["InputName"]; isPresent { + pd.InputName = inpName.(string) + } + if avgRows, isPresent := data["AvgNumberOfRows"]; isPresent { + pd.RowsReceived = RowsReceived{ + int(avgRows.(float64)), + } + } + if sq, isPresent := data["ShardsQueried"]; isPresent { + sq := int(sq.(float64)) + pd.ShardsQueried = (*ShardsQueried)(&sq) + } + if inputs, isPresent := data["Inputs"]; isPresent { + inputs := inputs.([]any) + for _, input := range inputs { + inputMap := input.(map[string]any) + inp, err := PrimitiveDescriptionFromMap(inputMap) + if err != nil { + return PrimitiveDescription{}, err + } + pd.Inputs = append(pd.Inputs, inp) + } + } + return pd, nil +} + +// WalkPrimitiveDescription walks the primitive description. +func WalkPrimitiveDescription(pd PrimitiveDescription, f func(PrimitiveDescription)) { + f(pd) + for _, child := range pd.Inputs { + WalkPrimitiveDescription(child, f) + } +} + +func (pd PrimitiveDescription) Equals(other PrimitiveDescription) string { + if pd.Variant != other.Variant { + return fmt.Sprintf("Variant: %v != %v", pd.Variant, other.Variant) + } + + if pd.OperatorType != other.OperatorType { + return fmt.Sprintf("OperatorType: %v != %v", pd.OperatorType, other.OperatorType) + } + + // TODO (harshit): enable this to compare keyspace as well + // switch { + // case pd.Keyspace == nil && other.Keyspace == nil: + // // do nothing + // case pd.Keyspace != nil && other.Keyspace != nil: + // if pd.Keyspace.Name != other.Keyspace.Name { + // return fmt.Sprintf("Keyspace.Name: %v != %v", pd.Keyspace.Name, other.Keyspace.Name) + // } + // default: + // return "Keyspace is nil in one of the descriptions" + // } + + switch { + case pd.TargetDestination == nil && other.TargetDestination == nil: + // do nothing + case pd.TargetDestination != nil && other.TargetDestination != nil: + if pd.TargetDestination.String() != other.TargetDestination.String() { + return fmt.Sprintf("TargetDestination: %v != %v", pd.TargetDestination, other.TargetDestination) + } + default: + return "TargetDestination is nil in one of the descriptions" + } + + if pd.TargetTabletType != other.TargetTabletType { + return fmt.Sprintf("TargetTabletType: %v != %v", pd.TargetTabletType, other.TargetTabletType) + } + + switch { + case pd.Other == nil && other.Other == nil: + // do nothing + case pd.Other != nil && other.Other != nil: + if len(pd.Other) != len(other.Other) { + return fmt.Sprintf("Other length did not match: %v != %v", pd.Other, other.Other) + } + for ky, val := range pd.Other { + if other.Other[ky] != val { + return fmt.Sprintf("Other[%v]: %v != %v", ky, val, other.Other[ky]) + } + } + default: + return "Other is nil in one of the descriptions" + } + if len(pd.Inputs) != len(other.Inputs) { + return fmt.Sprintf("Inputs length did not match: %v != %v", len(pd.Inputs), len(other.Inputs)) + } + for idx, input := range pd.Inputs { + if diff := input.Equals(other.Inputs[idx]); diff != "" { + return diff + } + } + return "" +} + func average(nums []int) float64 { total := 0 for _, num := range nums { diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index 4f3a388d04f..7734dd81a6b 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -70,9 +70,9 @@ type ( StreamExecutePrimitiveStandalone(ctx context.Context, primitive Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(result *sqltypes.Result) error) error // Shard-level functions. - ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) - ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) - StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error + ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) + ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) + StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error // Keyspace ID level functions. ExecuteKeyspaceID(ctx context.Context, keyspace string, ksid []byte, query string, bindVars map[string]*querypb.BindVariable, rollbackOnError, autocommit bool) (*sqltypes.Result, error) @@ -147,6 +147,8 @@ type ( // RecordMirrorStats is used to record stats about a mirror query. RecordMirrorStats(time.Duration, time.Duration, error) + + SetLastInsertID(uint64) } // SessionActions gives primitives ability to interact with the session state diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 59682dd91fe..20ab7695f70 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -95,6 +95,8 @@ type Route struct { // select count(*) from tbl where lookupColumn = 'not there' // select exists() NoRoutesSpecialHandling bool + + FetchLastInsertID bool } // NewRoute creates a Route. @@ -181,7 +183,7 @@ func (route *Route) executeShards( } queries := getQueries(route.Query, bvs) - result, errs := vcursor.ExecuteMultiShard(ctx, route, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + result, errs := vcursor.ExecuteMultiShard(ctx, route, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, route.FetchLastInsertID) route.executeWarmingReplicaRead(ctx, vcursor, bindVars, queries) @@ -278,7 +280,7 @@ func (route *Route) streamExecuteShards( } if len(route.OrderBy) == 0 { - errs := vcursor.StreamExecuteMulti(ctx, route, route.Query, rss, bvs, false /* rollbackOnError */, false /* autocommit */, func(qr *sqltypes.Result) error { + errs := vcursor.StreamExecuteMulti(ctx, route, route.Query, rss, bvs, false /* rollbackOnError */, false /* autocommit */, route.FetchLastInsertID, func(qr *sqltypes.Result) error { return callback(qr.Truncate(route.TruncateColumnCount)) }) if len(errs) > 0 { @@ -316,10 +318,12 @@ func (route *Route) mergeSort( primitive: route, }) } + ms := MergeSort{ Primitives: prims, OrderBy: route.OrderBy, ScatterErrorsAsWarnings: route.ScatterErrorsAsWarnings, + FetchLastInsertID: route.FetchLastInsertID, } return vcursor.StreamExecutePrimitive(ctx, &ms, bindVars, wantfields, func(qr *sqltypes.Result) error { return callback(qr.Truncate(route.TruncateColumnCount)) @@ -351,7 +355,7 @@ func (route *Route) GetFields(ctx context.Context, vcursor VCursor, bindVars map } rs = rss[0] } - qr, err := execShard(ctx, route, vcursor, route.FieldQuery, bindVars, rs, false /* rollbackOnError */, false /* canAutocommit */) + qr, err := execShard(ctx, route, vcursor, route.FieldQuery, bindVars, rs, false /* rollbackOnError */, false /* canAutocommit */, route.FetchLastInsertID) if err != nil { return nil, err } @@ -374,6 +378,9 @@ func (route *Route) description() PrimitiveDescription { "Table": route.GetTableName(), "FieldQuery": route.FieldQuery, } + if route.FetchLastInsertID { + other["FetchLastInsertID"] = true + } if route.Vindex != nil { other["Vindex"] = route.Vindex.String() } @@ -479,7 +486,7 @@ func execShard( query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, - rollbackOnError, canAutocommit bool, + rollbackOnError, canAutocommit, fetchLastInsertID bool, ) (*sqltypes.Result, error) { autocommit := canAutocommit && vcursor.AutocommitApproval() result, errs := vcursor.ExecuteMultiShard(ctx, primitive, []*srvtopo.ResolvedShard{rs}, []*querypb.BoundQuery{ @@ -487,7 +494,7 @@ func execShard( Sql: query, BindVariables: bindVars, }, - }, rollbackOnError, autocommit) + }, rollbackOnError, autocommit, fetchLastInsertID) return result, vterrors.Aggregate(errs) } @@ -534,7 +541,7 @@ func (route *Route) executeWarmingReplicaRead(ctx context.Context, vcursor VCurs return } - _, errs := replicaVCursor.ExecuteMultiShard(ctx, route, rss, queries, false /* rollbackOnError */, false /* autocommit */) + _, errs := replicaVCursor.ExecuteMultiShard(ctx, route, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, route.FetchLastInsertID) if len(errs) > 0 { log.Warningf("Failed to execute warming replica read: %v", errs) } else { diff --git a/go/vt/vtgate/engine/routing.go b/go/vt/vtgate/engine/routing.go index e05366c4aeb..067278c1a93 100644 --- a/go/vt/vtgate/engine/routing.go +++ b/go/vt/vtgate/engine/routing.go @@ -51,6 +51,9 @@ const ( // IN is for routing a statement to a multi shard. // Requires: A Vindex, and a multi Values. IN + // Between is for routing a statement to a multi shard + // Requires: A Vindex, and start and end Value. + Between // MultiEqual is used for routing queries with IN with tuple clause // Requires: A Vindex, and a multi Tuple Values. MultiEqual @@ -78,6 +81,7 @@ var opName = map[Opcode]string{ EqualUnique: "EqualUnique", Equal: "Equal", IN: "IN", + Between: "Between", MultiEqual: "MultiEqual", Scatter: "Scatter", DBA: "DBA", @@ -157,6 +161,14 @@ func (rp *RoutingParameters) findRoute(ctx context.Context, vcursor VCursor, bin default: return rp.in(ctx, vcursor, bindVars) } + case Between: + switch rp.Vindex.(type) { + case vindexes.SingleColumn: + return rp.between(ctx, vcursor, bindVars) + default: + // Only SingleColumn vindex supported. + return nil, nil, vterrors.VT13001("between supported on SingleColumn vindex only") + } case MultiEqual: switch rp.Vindex.(type) { case vindexes.MultiColumn: @@ -396,6 +408,19 @@ func (rp *RoutingParameters) inMultiCol(ctx context.Context, vcursor VCursor, bi return rss, shardVarsMultiCol(bindVars, mapVals, isSingleVal), nil } +func (rp *RoutingParameters) between(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) ([]*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, error) { + env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) + value, err := env.Evaluate(rp.Values[0]) + if err != nil { + return nil, nil, err + } + rss, values, err := resolveShardsBetween(ctx, vcursor, rp.Vindex.(vindexes.Sequential), rp.Keyspace, value.TupleValues()) + if err != nil { + return nil, nil, err + } + return rss, shardVars(bindVars, values), nil +} + func (rp *RoutingParameters) multiEqual(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) ([]*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, error) { env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) value, err := env.Evaluate(rp.Values[0]) @@ -520,6 +545,24 @@ func buildMultiColumnVindexValues(shardsValues [][][]sqltypes.Value) [][][]*quer return shardsIds } +func resolveShardsBetween(ctx context.Context, vcursor VCursor, vindex vindexes.Sequential, keyspace *vindexes.Keyspace, vindexKeys []sqltypes.Value) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error) { + // Convert vindexKeys to []*querypb.Value + ids := make([]*querypb.Value, len(vindexKeys)) + for i, vik := range vindexKeys { + ids[i] = sqltypes.ValueToProto(vik) + } + + // RangeMap using the Vindex + destinations, err := vindex.RangeMap(ctx, vcursor, vindexKeys[0], vindexKeys[1]) + if err != nil { + return nil, nil, err + + } + + // And use the Resolver to map to ResolvedShards. + return vcursor.ResolveDestinations(ctx, keyspace.Name, ids, destinations) +} + func shardVars(bv map[string]*querypb.BindVariable, mapVals [][]*querypb.Value) []map[string]*querypb.BindVariable { shardVars := make([]map[string]*querypb.BindVariable, len(mapVals)) for i, vals := range mapVals { diff --git a/go/vt/vtgate/engine/semi_join.go b/go/vt/vtgate/engine/semi_join.go index f0dd0d09033..b5bc74a5941 100644 --- a/go/vt/vtgate/engine/semi_join.go +++ b/go/vt/vtgate/engine/semi_join.go @@ -18,6 +18,7 @@ package engine import ( "context" + "sync/atomic" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -62,24 +63,26 @@ func (jn *SemiJoin) TryExecute(ctx context.Context, vcursor VCursor, bindVars ma // TryStreamExecute performs a streaming exec. func (jn *SemiJoin) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - joinVars := make(map[string]*querypb.BindVariable) err := vcursor.StreamExecutePrimitive(ctx, jn.Left, bindVars, wantfields, func(lresult *sqltypes.Result) error { + joinVars := make(map[string]*querypb.BindVariable) result := &sqltypes.Result{Fields: lresult.Fields} for _, lrow := range lresult.Rows { for k, col := range jn.Vars { joinVars[k] = sqltypes.ValueBindVariable(lrow[col]) } - rowAdded := false + var rowAdded atomic.Bool err := vcursor.StreamExecutePrimitive(ctx, jn.Right, combineVars(bindVars, joinVars), false, func(rresult *sqltypes.Result) error { - if len(rresult.Rows) > 0 && !rowAdded { - result.Rows = append(result.Rows, lrow) - rowAdded = true + if len(rresult.Rows) > 0 { + rowAdded.Store(true) } return nil }) if err != nil { return err } + if rowAdded.Load() { + result.Rows = append(result.Rows, lrow) + } } return callback(result) }) diff --git a/go/vt/vtgate/engine/semi_join_test.go b/go/vt/vtgate/engine/semi_join_test.go index 8fee0490415..a103b0686b2 100644 --- a/go/vt/vtgate/engine/semi_join_test.go +++ b/go/vt/vtgate/engine/semi_join_test.go @@ -18,6 +18,7 @@ package engine import ( "context" + "sync" "testing" "vitess.io/vitess/go/test/utils" @@ -159,3 +160,81 @@ func TestSemiJoinStreamExecute(t *testing.T) { "4|d|dd", )) } + +// TestSemiJoinStreamExecuteParallelExecution tests SemiJoin stream execution with parallel execution +// to ensure we have no data races. +func TestSemiJoinStreamExecuteParallelExecution(t *testing.T) { + leftPrim := &fakePrimitive{ + results: []*sqltypes.Result{ + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1|col2|col3", + "int64|varchar|varchar", + ), + "1|a|aa", + "2|b|bb", + ), sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1|col2|col3", + "int64|varchar|varchar", + ), + "3|c|cc", + "4|d|dd", + ), + }, + async: true, + } + rightFields := sqltypes.MakeTestFields( + "col4|col5|col6", + "int64|varchar|varchar", + ) + rightPrim := &fakePrimitive{ + // we'll return non-empty results for rows 2 and 4 + results: sqltypes.MakeTestStreamingResults(rightFields, + "4|d|dd", + "---", + "---", + "5|e|ee", + "6|f|ff", + "7|g|gg", + ), + async: true, + noLog: true, + } + + jn := &SemiJoin{ + Left: leftPrim, + Right: rightPrim, + Vars: map[string]int{ + "bv": 1, + }, + } + var res *sqltypes.Result + var mu sync.Mutex + err := jn.TryStreamExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{}, true, func(result *sqltypes.Result) error { + mu.Lock() + defer mu.Unlock() + if res == nil { + res = result + } else { + res.Rows = append(res.Rows, result.Rows...) + } + return nil + }) + require.NoError(t, err) + leftPrim.ExpectLog(t, []string{ + `StreamExecute true`, + }) + // We'll get all the rows back in left primitive, since we're returning the same set of rows + // from the right primitive that makes them all qualify. + expectResultAnyOrder(t, res, sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1|col2|col3", + "int64|varchar|varchar", + ), + "1|a|aa", + "2|b|bb", + "3|c|cc", + "4|d|dd", + )) +} diff --git a/go/vt/vtgate/engine/send.go b/go/vt/vtgate/engine/send.go index 2ebec5c679e..4655f680675 100644 --- a/go/vt/vtgate/engine/send.go +++ b/go/vt/vtgate/engine/send.go @@ -116,7 +116,7 @@ func (s *Send) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[str } rollbackOnError := s.IsDML // for non-dml queries, there's no need to do a rollback - result, errs := vcursor.ExecuteMultiShard(ctx, s, rss, queries, rollbackOnError, s.canAutoCommit(vcursor, rss)) + result, errs := vcursor.ExecuteMultiShard(ctx, s, rss, queries, rollbackOnError, s.canAutoCommit(vcursor, rss), false) err = vterrors.Aggregate(errs) if err != nil { return nil, err @@ -179,7 +179,7 @@ func (s *Send) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars m } multiBindVars[i] = bv } - errors := vcursor.StreamExecuteMulti(ctx, s, s.Query, rss, multiBindVars, s.IsDML, s.canAutoCommit(vcursor, rss), callback) + errors := vcursor.StreamExecuteMulti(ctx, s, s.Query, rss, multiBindVars, s.IsDML, s.canAutoCommit(vcursor, rss), false, callback) return vterrors.Aggregate(errors) } diff --git a/go/vt/vtgate/engine/set.go b/go/vt/vtgate/engine/set.go index 9d370b6ec36..f0de330cbed 100644 --- a/go/vt/vtgate/engine/set.go +++ b/go/vt/vtgate/engine/set.go @@ -22,23 +22,18 @@ import ( "fmt" "strings" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/sysvars" - - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" - - "vitess.io/vitess/go/vt/log" - - "vitess.io/vitess/go/vt/srvtopo" - - "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" + vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/schema" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -248,7 +243,7 @@ func (svci *SysVarCheckAndIgnore) Execute(ctx context.Context, vcursor VCursor, return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Unexpected error, DestinationKeyspaceID mapping to multiple shards: %v", svci.TargetDestination) } checkSysVarQuery := fmt.Sprintf("select 1 from dual where @@%s = %s", svci.Name, svci.Expr) - _, err = execShard(ctx, nil, vcursor, checkSysVarQuery, env.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */) + _, err = execShard(ctx, nil, vcursor, checkSysVarQuery, env.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */, false) if err != nil { // Rather than returning the error, we will just log the error // as the intention for executing the query it to validate the current setting and eventually ignore it anyways. @@ -308,7 +303,7 @@ func (svs *SysVarReservedConn) Execute(ctx context.Context, vcursor VCursor, env BindVariables: env.BindVars, } } - _, errs := vcursor.ExecuteMultiShard(ctx, nil, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + _, errs := vcursor.ExecuteMultiShard(ctx, nil /*primitive*/, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, false /*fetchLastInsertID*/) return vterrors.Aggregate(errs) } @@ -320,7 +315,7 @@ func (svs *SysVarReservedConn) execSetStatement(ctx context.Context, vcursor VCu BindVariables: env.BindVars, } } - _, errs := vcursor.ExecuteMultiShard(ctx, nil, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + _, errs := vcursor.ExecuteMultiShard(ctx, nil /*primitive*/, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, false /*fetchLastInsertID*/) return vterrors.Aggregate(errs) } @@ -333,7 +328,7 @@ func (svs *SysVarReservedConn) checkAndUpdateSysVar(ctx context.Context, vcursor if err != nil { return false, err } - qr, err := execShard(ctx, nil, vcursor, sysVarExprValidationQuery, res.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */) + qr, err := execShard(ctx, nil /*primitive*/, vcursor, sysVarExprValidationQuery, res.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */, false /*fetchLastInsertID*/) if err != nil { return false, err } diff --git a/go/vt/vtgate/engine/shard_route.go b/go/vt/vtgate/engine/shard_route.go index 8365c6fdf59..1e901b9a8ea 100644 --- a/go/vt/vtgate/engine/shard_route.go +++ b/go/vt/vtgate/engine/shard_route.go @@ -37,8 +37,8 @@ type shardRoute struct { } // StreamExecute performs a streaming exec. -func (sr *shardRoute) StreamExecute(ctx context.Context, vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool, callback func(*sqltypes.Result) error) error { +func (sr *shardRoute) StreamExecute(ctx context.Context, vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool, fetchLastInsertID bool, callback func(*sqltypes.Result) error) error { // TODO rollback on error and autocommit should probably not be used like this - errors := vcursor.StreamExecuteMulti(ctx, sr.primitive, sr.query, []*srvtopo.ResolvedShard{sr.rs}, []map[string]*querypb.BindVariable{sr.bv}, false /* rollbackOnError */, false /* autocommit */, callback) + errors := vcursor.StreamExecuteMulti(ctx, sr.primitive, sr.query, []*srvtopo.ResolvedShard{sr.rs}, []map[string]*querypb.BindVariable{sr.bv}, false /* rollbackOnError */, false /* autocommit */, fetchLastInsertID, callback) return vterrors.Aggregate(errors) } diff --git a/go/vt/vtgate/engine/unlock.go b/go/vt/vtgate/engine/unlock.go index 5addbb957fa..1047abb6ec5 100644 --- a/go/vt/vtgate/engine/unlock.go +++ b/go/vt/vtgate/engine/unlock.go @@ -60,7 +60,7 @@ func (u *Unlock) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[s for i := 0; i < len(rss); i++ { bqs[i] = &querypb.BoundQuery{Sql: unlockTables} } - qr, errs := vcursor.ExecuteMultiShard(ctx, u, rss, bqs, true, false) + qr, errs := vcursor.ExecuteMultiShard(ctx, u, rss, bqs, true, false, false) return qr, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/update.go b/go/vt/vtgate/engine/update.go index 27ca9ad12a1..49c8576fd84 100644 --- a/go/vt/vtgate/engine/update.go +++ b/go/vt/vtgate/engine/update.go @@ -102,7 +102,7 @@ func (upd *Update) updateVindexEntries(ctx context.Context, vcursor VCursor, bin for i := range rss { queries[i] = &querypb.BoundQuery{Sql: upd.OwnedVindexQuery, BindVariables: bindVars} } - subQueryResult, errors := vcursor.ExecuteMultiShard(ctx, upd, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + subQueryResult, errors := vcursor.ExecuteMultiShard(ctx, upd, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, upd.FetchLastInsertID) for _, err := range errors { if err != nil { return err @@ -214,6 +214,9 @@ func (upd *Update) description() PrimitiveDescription { if len(changedVindexes) > 0 { other["ChangedVindexValues"] = changedVindexes } + if upd.FetchLastInsertID { + other["FetchLastInsertID"] = upd.FetchLastInsertID + } return PrimitiveDescription{ OperatorType: "Update", diff --git a/go/vt/vtgate/engine/vexplain.go b/go/vt/vtgate/engine/vexplain.go index 78941e8160f..0785f4d25ce 100644 --- a/go/vt/vtgate/engine/vexplain.go +++ b/go/vt/vtgate/engine/vexplain.go @@ -207,7 +207,7 @@ func (v *VExplain) convertToVExplainAllResult(ctx context.Context, vcursor VCurs res, err := vcursor.ExecuteStandalone(ctx, nil, explainQuery, nil, &srvtopo.ResolvedShard{ Target: entry.Target, Gateway: entry.Gateway, - }) + }, false) if err != nil { return nil, err } diff --git a/go/vt/vtgate/evalengine/arena.go b/go/vt/vtgate/evalengine/arena.go index ccfe63f514f..c5457f076e8 100644 --- a/go/vt/vtgate/evalengine/arena.go +++ b/go/vt/vtgate/evalengine/arena.go @@ -71,7 +71,7 @@ func (a *Arena) newEvalEnum(raw []byte, values *EnumSetValues) *evalEnum { } else { a.aEnum = append(a.aEnum, evalEnum{}) } - val := &a.aEnum[len(a.aInt64)-1] + val := &a.aEnum[len(a.aEnum)-1] s := string(raw) val.string = s val.value = valueIdx(values, s) @@ -84,7 +84,7 @@ func (a *Arena) newEvalSet(raw []byte, values *EnumSetValues) *evalSet { } else { a.aSet = append(a.aSet, evalSet{}) } - val := &a.aSet[len(a.aInt64)-1] + val := &a.aSet[len(a.aSet)-1] s := string(raw) val.string = s val.set = evalSetBits(values, s) diff --git a/go/vt/vtgate/evalengine/cached_size.go b/go/vt/vtgate/evalengine/cached_size.go index c1ed1f9475c..b953afda95c 100644 --- a/go/vt/vtgate/evalengine/cached_size.go +++ b/go/vt/vtgate/evalengine/cached_size.go @@ -175,6 +175,20 @@ func (cached *Column) CachedSize(alloc bool) int64 { } return size } +func (cached *Comparison) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(56)) + for _, elem := range *cached { + size += elem.CachedSize(false) + } + return size +} func (cached *ComparisonExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -245,6 +259,20 @@ func (cached *ConvertUsingExpr) CachedSize(alloc bool) int64 { size += cached.CollationEnv.CachedSize(true) return size } +func (cached *EnumSetValues) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + size += hack.RuntimeAllocSize(int64(len(elem))) + } + return size +} func (cached *InExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -391,6 +419,22 @@ func (cached *TupleBindVariable) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Key))) return size } +func (cached *TupleExpr) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + size += hack.RuntimeAllocSize(int64(cap(*cached)) * int64(16)) + for _, elem := range *cached { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + return size +} func (cached *Type) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -1181,6 +1225,18 @@ func (cached *builtinLastDay) CachedSize(alloc bool) int64 { size += cached.CallExpr.CachedSize(false) return size } +func (cached *builtinLastInsertID) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(48) + } + // field CallExpr vitess.io/vitess/go/vt/vtgate/evalengine.CallExpr + size += cached.CallExpr.CachedSize(false) + return size +} func (cached *builtinLeftRight) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -2102,6 +2158,9 @@ func (cached *evalYear) CachedSize(alloc bool) int64 { } return size } +func (cached *frame) CachedSize(alloc bool) int64 { + return int64(0) +} func (cached *typedExpr) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vtgate/evalengine/compiler_asm.go b/go/vt/vtgate/evalengine/compiler_asm.go index dfb1a30bffc..7dda215353f 100644 --- a/go/vt/vtgate/evalengine/compiler_asm.go +++ b/go/vt/vtgate/evalengine/compiler_asm.go @@ -5138,3 +5138,18 @@ func (asm *assembler) Introduce(offset int, t sqltypes.Type, col collations.Type return 1 }, "INTRODUCE (SP-1)") } + +func (asm *assembler) Fn_LAST_INSERT_ID() { + asm.emit(func(env *ExpressionEnv) int { + arg := env.vm.stack[env.vm.sp-1] + if arg == nil { + env.VCursor().SetLastInsertID(0) + } else { + iarg := evalToInt64(arg) + uarg := env.vm.arena.newEvalUint64(uint64(iarg.i)) + env.vm.stack[env.vm.sp-1] = uarg + env.VCursor().SetLastInsertID(uarg.u) + } + return 1 + }, "FN LAST_INSERT_ID UINT64(SP-1)") +} diff --git a/go/vt/vtgate/evalengine/compiler_test.go b/go/vt/vtgate/evalengine/compiler_test.go index cb9b99e7776..343bb0cd043 100644 --- a/go/vt/vtgate/evalengine/compiler_test.go +++ b/go/vt/vtgate/evalengine/compiler_test.go @@ -740,6 +740,40 @@ func TestCompilerSingle(t *testing.T) { expression: `cast(_utf32 0x0000FF as binary)`, result: `VARBINARY("\x00\x00\x00\xff")`, }, + { + expression: `DATE_FORMAT(timestamp '2024-12-30 10:34:58', "%u")`, + result: `VARCHAR("53")`, + }, + { + expression: `WEEK(timestamp '2024-12-30 10:34:58', 0)`, + result: `INT64(52)`, + }, + { + expression: `WEEK(timestamp '2024-12-30 10:34:58', 1)`, + result: `INT64(53)`, + }, + { + expression: `WEEK(timestamp '2024-01-01 10:34:58', 0)`, + result: `INT64(0)`, + }, + { + expression: `WEEK(timestamp '2024-01-01 10:34:58', 1)`, + result: `INT64(1)`, + }, + { + expression: `column0 + 1`, + values: []sqltypes.Value{sqltypes.MakeTrusted(sqltypes.Enum, []byte("foo"))}, + // Returns 0, as unknown enums evaluate here to -1. We have this test to + // exercise the path to push enums onto the stack. + result: `FLOAT64(0)`, + }, + { + expression: `column0 + 1`, + values: []sqltypes.Value{sqltypes.MakeTrusted(sqltypes.Set, []byte("foo"))}, + // Returns 1, as unknown sets evaluate here to 0. We have this test to + // exercise the path to push sets onto the stack. + result: `FLOAT64(1)`, + }, } tz, _ := time.LoadLocation("Europe/Madrid") @@ -883,6 +917,99 @@ func TestBindVarLiteral(t *testing.T) { } } +type testVcursor struct { + lastInsertID *uint64 + env *vtenv.Environment +} + +func (t *testVcursor) TimeZone() *time.Location { + return time.UTC +} + +func (t *testVcursor) GetKeyspace() string { + return "apa" +} + +func (t *testVcursor) SQLMode() string { + return "oltp" +} + +func (t *testVcursor) Environment() *vtenv.Environment { + return t.env +} + +func (t *testVcursor) SetLastInsertID(id uint64) { + t.lastInsertID = &id +} + +var _ evalengine.VCursor = (*testVcursor)(nil) + +func TestLastInsertID(t *testing.T) { + var testCases = []struct { + expression string + result uint64 + missing bool + }{ + { + expression: `last_insert_id(1)`, + result: 1, + }, { + expression: `12`, + missing: true, + }, { + expression: `last_insert_id(666)`, + result: 666, + }, { + expression: `last_insert_id(null)`, + result: 0, + }, + } + + venv := vtenv.NewTestEnv() + for _, tc := range testCases { + t.Run(tc.expression, func(t *testing.T) { + expr, err := venv.Parser().ParseExpr(tc.expression) + require.NoError(t, err) + + cfg := &evalengine.Config{ + Collation: collations.CollationUtf8mb4ID, + NoConstantFolding: true, + NoCompilation: false, + Environment: venv, + } + t.Run("eval", func(t *testing.T) { + cfg.NoCompilation = true + runTest(t, expr, cfg, tc) + }) + t.Run("compiled", func(t *testing.T) { + cfg.NoCompilation = false + runTest(t, expr, cfg, tc) + }) + }) + } +} + +func runTest(t *testing.T, expr sqlparser.Expr, cfg *evalengine.Config, tc struct { + expression string + result uint64 + missing bool +}) { + converted, err := evalengine.Translate(expr, cfg) + require.NoError(t, err) + + vc := &testVcursor{env: vtenv.NewTestEnv()} + env := evalengine.NewExpressionEnv(context.Background(), nil, vc) + + _, err = env.Evaluate(converted) + require.NoError(t, err) + if tc.missing { + require.Nil(t, vc.lastInsertID) + } else { + require.NotNil(t, vc.lastInsertID) + require.Equal(t, tc.result, *vc.lastInsertID) + } +} + func TestCompilerNonConstant(t *testing.T) { var testCases = []struct { expression string diff --git a/go/vt/vtgate/evalengine/expr_env.go b/go/vt/vtgate/evalengine/expr_env.go index 38a65f9b4e0..4a7f9849ab0 100644 --- a/go/vt/vtgate/evalengine/expr_env.go +++ b/go/vt/vtgate/evalengine/expr_env.go @@ -35,6 +35,7 @@ type VCursor interface { GetKeyspace() string SQLMode() string Environment() *vtenv.Environment + SetLastInsertID(id uint64) } type ( @@ -140,6 +141,7 @@ func (e *emptyVCursor) GetKeyspace() string { func (e *emptyVCursor) SQLMode() string { return config.DefaultSQLMode } +func (e *emptyVCursor) SetLastInsertID(_ uint64) {} func NewEmptyVCursor(env *vtenv.Environment, tz *time.Location) VCursor { return &emptyVCursor{env: env, tz: tz} diff --git a/go/vt/vtgate/evalengine/fn_misc.go b/go/vt/vtgate/evalengine/fn_misc.go index 8813b62f823..2a2119ee6f4 100644 --- a/go/vt/vtgate/evalengine/fn_misc.go +++ b/go/vt/vtgate/evalengine/fn_misc.go @@ -81,6 +81,10 @@ type ( builtinUUIDToBin struct { CallExpr } + + builtinLastInsertID struct { + CallExpr + } ) var _ IR = (*builtinInetAton)(nil) @@ -95,6 +99,7 @@ var _ IR = (*builtinBinToUUID)(nil) var _ IR = (*builtinIsUUID)(nil) var _ IR = (*builtinUUID)(nil) var _ IR = (*builtinUUIDToBin)(nil) +var _ IR = (*builtinLastInsertID)(nil) func (call *builtinInetAton) eval(env *ExpressionEnv) (eval, error) { arg, err := call.arg1(env) @@ -194,6 +199,33 @@ func (call *builtinInet6Aton) compile(c *compiler) (ctype, error) { return ctype{Type: sqltypes.VarBinary, Flag: flagNullable, Col: collationBinary}, nil } +func (call *builtinLastInsertID) eval(env *ExpressionEnv) (eval, error) { + arg, err := call.arg1(env) + if err != nil { + return nil, err + } + if arg == nil { + env.VCursor().SetLastInsertID(0) + return nil, err + } + insertID := uint64(evalToInt64(arg).i) + env.VCursor().SetLastInsertID(insertID) + return newEvalUint64(insertID), nil +} + +func (call *builtinLastInsertID) compile(c *compiler) (ctype, error) { + arg, err := call.Arguments[0].compile(c) + if err != nil { + return ctype{}, err + } + c.asm.Fn_LAST_INSERT_ID() + return ctype{Type: sqltypes.Uint64, Flag: arg.Flag & flagNullable, Col: collationNumeric}, nil +} + +func (call *builtinLastInsertID) constant() bool { + return false // we don't want this function to be simplified away +} + func printIPv6AsIPv4(addr netip.Addr) (netip.Addr, bool) { b := addr.AsSlice() if len(b) != 16 { diff --git a/go/vt/vtgate/evalengine/fn_time.go b/go/vt/vtgate/evalengine/fn_time.go index 2d5e12f518d..322b89faafb 100644 --- a/go/vt/vtgate/evalengine/fn_time.go +++ b/go/vt/vtgate/evalengine/fn_time.go @@ -256,7 +256,7 @@ func (call *builtinNow) constant() bool { func (call *builtinSysdate) eval(env *ExpressionEnv) (eval, error) { now := SystemTime() - if tz := env.currentTimezone(); tz != nil { + if tz := env.currentTimezone(); tz != time.Local { now = now.In(tz) } return newEvalDateTime(datetime.NewDateTimeFromStd(now), int(call.prec), false), nil @@ -701,7 +701,7 @@ func (b *builtinFromUnixtime) eval(env *ExpressionEnv) (eval, error) { } t := time.Unix(sec, frac) - if tz := env.currentTimezone(); tz != nil { + if tz := env.currentTimezone(); tz != time.Local { t = t.In(tz) } diff --git a/go/vt/vtgate/evalengine/integration/comparison_test.go b/go/vt/vtgate/evalengine/integration/comparison_test.go index ea327601975..d559cb8ab1d 100644 --- a/go/vt/vtgate/evalengine/integration/comparison_test.go +++ b/go/vt/vtgate/evalengine/integration/comparison_test.go @@ -209,6 +209,10 @@ type vcursor struct { env *vtenv.Environment } +func (vc *vcursor) SetLastInsertID(id uint64) {} + +var _ evalengine.VCursor = (*vcursor)(nil) + func (vc *vcursor) GetKeyspace() string { return "vttest" } diff --git a/go/vt/vtgate/evalengine/testcases/inputs.go b/go/vt/vtgate/evalengine/testcases/inputs.go index ac23281fd54..4c65cc5002f 100644 --- a/go/vt/vtgate/evalengine/testcases/inputs.go +++ b/go/vt/vtgate/evalengine/testcases/inputs.go @@ -108,6 +108,7 @@ var inputConversions = []string{ "time '10:04:58'", "time '31:34:58'", "time '32:34:58'", "time '130:34:58'", "time '5 10:34:58'", "time '10:04:58.1'", "time '31:34:58.4'", "time '32:34:58.5'", "time '130:34:58.6'", "time '5 10:34:58.9'", "date '2000-01-01'", "timestamp '2000-01-01 10:34:58'", "timestamp '2000-01-01 10:34:58.123456'", "timestamp '2000-01-01 10:34:58.978654'", + "timestamp '2024-12-30 10:34:58'", "20000101103458", "20000101103458.1234", "20000101103458.123456", "20000101", "103458", "103458.123456", "'20000101103458'", "'20000101103458.1234'", "'20000101103458.123456'", "'20000101'", "'103458'", "'103458.123456'", "'20000101103458foo'", "'20000101103458.1234foo'", "'20000101103458.123456foo'", "'20000101foo'", "'103458foo'", "'103458.123456foo'", diff --git a/go/vt/vtgate/evalengine/translate_builtin.go b/go/vt/vtgate/evalengine/translate_builtin.go index 476ee32483b..1f8bd7798aa 100644 --- a/go/vt/vtgate/evalengine/translate_builtin.go +++ b/go/vt/vtgate/evalengine/translate_builtin.go @@ -662,6 +662,11 @@ func (ast *astCompiler) translateFuncExpr(fn *sqlparser.FuncExpr) (IR, error) { return nil, argError(method) } return &builtinReplace{CallExpr: call, collate: ast.cfg.Collation}, nil + case "last_insert_id": + if len(args) != 1 { + return nil, argError(method) + } + return &builtinLastInsertID{CallExpr: call}, nil default: return nil, translateExprNotSupported(fn) } diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index e84ab7fbb21..c8dfd0b6269 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -31,6 +31,7 @@ import ( "github.com/spf13/pflag" vschemapb "vitess.io/vitess/go/vt/proto/vschema" + "vitess.io/vitess/go/vt/vtgate/dynamicconfig" "vitess.io/vitess/go/acl" "vitess.io/vitess/go/cache/theine" @@ -106,38 +107,45 @@ func init() { // Executor is the engine that executes queries by utilizing // the abilities of the underlying vttablets. -type Executor struct { - env *vtenv.Environment - serv srvtopo.Server - cell string - resolver *Resolver - scatterConn *ScatterConn - txConn *TxConn +type ( + ExecutorConfig struct { + Normalize bool + StreamSize int + // AllowScatter will fail planning if set to false and a plan contains any scatter queries + AllowScatter bool + WarmingReadsPercent int + QueryLogToFile string + } - mu sync.Mutex - vschema *vindexes.VSchema - streamSize int - vschemaStats *VSchemaStats + Executor struct { + config ExecutorConfig - plans *PlanCache - epoch atomic.Uint32 + env *vtenv.Environment + serv srvtopo.Server + cell string + resolver *Resolver + scatterConn *ScatterConn + txConn *TxConn - normalize bool + mu sync.Mutex + vschema *vindexes.VSchema + vschemaStats *VSchemaStats - vm *VSchemaManager - schemaTracker SchemaInfo + plans *PlanCache + epoch atomic.Uint32 - // allowScatter will fail planning if set to false and a plan contains any scatter queries - allowScatter bool + vm *VSchemaManager + schemaTracker SchemaInfo - // queryLogger is passed in for logging from this vtgate executor. - queryLogger *streamlog.StreamLogger[*logstats.LogStats] + // queryLogger is passed in for logging from this vtgate executor. + queryLogger *streamlog.StreamLogger[*logstats.LogStats] - warmingReadsPercent int - warmingReadsChannel chan bool + warmingReadsChannel chan bool - vConfig econtext.VCursorConfig -} + vConfig econtext.VCursorConfig + ddlConfig dynamicconfig.DDL + } +) var executorOnce sync.Once @@ -161,33 +169,30 @@ func NewExecutor( serv srvtopo.Server, cell string, resolver *Resolver, - normalize, warnOnShardedOnly bool, - streamSize int, + eConfig ExecutorConfig, + warnOnShardedOnly bool, plans *PlanCache, schemaTracker SchemaInfo, - noScatter bool, pv plancontext.PlannerVersion, - warmingReadsPercent int, + ddlConfig dynamicconfig.DDL, ) *Executor { e := &Executor{ - env: env, - serv: serv, - cell: cell, - resolver: resolver, - scatterConn: resolver.scatterConn, - txConn: resolver.scatterConn.txConn, - normalize: normalize, - streamSize: streamSize, + config: eConfig, + env: env, + serv: serv, + cell: cell, + resolver: resolver, + scatterConn: resolver.scatterConn, + txConn: resolver.scatterConn.txConn, + schemaTracker: schemaTracker, - allowScatter: !noScatter, plans: plans, - warmingReadsPercent: warmingReadsPercent, warmingReadsChannel: make(chan bool, warmingReadsConcurrency), + ddlConfig: ddlConfig, } // setting the vcursor config. e.initVConfig(warnOnShardedOnly, pv) - vschemaacl.Init() // we subscribe to update from the VSchemaManager e.vm = &VSchemaManager{ subscriber: e.SaveVSchema, @@ -231,13 +236,13 @@ func (e *Executor) Execute(ctx context.Context, mysqlCtx vtgateservice.MySQLConn trace.AnnotateSQL(span, sqlparser.Preview(sql)) defer span.Finish() - logStats := logstats.NewLogStats(ctx, method, sql, safeSession.GetSessionUUID(), bindVars) + logStats := logstats.NewLogStats(ctx, method, sql, safeSession.GetSessionUUID(), bindVars, streamlog.GetQueryLogConfig()) stmtType, result, err := e.execute(ctx, mysqlCtx, safeSession, sql, bindVars, logStats) logStats.Error = err if result == nil { - saveSessionStats(safeSession, stmtType, 0, 0, 0, err) + saveSessionStats(safeSession, stmtType, 0, 0, err) } else { - saveSessionStats(safeSession, stmtType, result.RowsAffected, result.InsertID, len(result.Rows), err) + saveSessionStats(safeSession, stmtType, result.RowsAffected, len(result.Rows), err) } if result != nil && len(result.Rows) > warnMemoryRows { warnings.Add("ResultsExceeded", 1) @@ -267,7 +272,6 @@ type streaminResultReceiver struct { stmtType sqlparser.StatementType rowsAffected uint64 rowsReturned int - insertID uint64 callback func(*sqltypes.Result) error } @@ -276,9 +280,6 @@ func (s *streaminResultReceiver) storeResultStats(typ sqlparser.StatementType, q defer s.mu.Unlock() s.rowsAffected += qr.RowsAffected s.rowsReturned += len(qr.Rows) - if qr.InsertID != 0 { - s.insertID = qr.InsertID - } s.stmtType = typ return s.callback(qr) } @@ -298,7 +299,7 @@ func (e *Executor) StreamExecute( trace.AnnotateSQL(span, sqlparser.Preview(sql)) defer span.Finish() - logStats := logstats.NewLogStats(ctx, method, sql, safeSession.GetSessionUUID(), bindVars) + logStats := logstats.NewLogStats(ctx, method, sql, safeSession.GetSessionUUID(), bindVars, streamlog.GetQueryLogConfig()) srr := &streaminResultReceiver{callback: callback} var err error @@ -328,7 +329,7 @@ func (e *Executor) StreamExecute( byteCount += col.Len() } - if byteCount >= e.streamSize { + if byteCount >= e.config.StreamSize { err := callback(result) seenResults.Store(true) result = &sqltypes.Result{} @@ -380,7 +381,7 @@ func (e *Executor) StreamExecute( err = e.newExecute(ctx, mysqlCtx, safeSession, sql, bindVars, logStats, resultHandler, srr.storeResultStats) logStats.Error = err - saveSessionStats(safeSession, srr.stmtType, srr.rowsAffected, srr.insertID, srr.rowsReturned, err) + saveSessionStats(safeSession, srr.stmtType, srr.rowsAffected, srr.rowsReturned, err) if srr.rowsReturned > warnMemoryRows { warnings.Add("ResultsExceeded", 1) piiSafeSQL, err := e.env.Parser().RedactSQLQuery(sql) @@ -413,7 +414,7 @@ func canReturnRows(stmtType sqlparser.StatementType) bool { } } -func saveSessionStats(safeSession *econtext.SafeSession, stmtType sqlparser.StatementType, rowsAffected, insertID uint64, rowsReturned int, err error) { +func saveSessionStats(safeSession *econtext.SafeSession, stmtType sqlparser.StatementType, rowsAffected uint64, rowsReturned int, err error) { safeSession.RowCount = -1 if err != nil { return @@ -421,9 +422,6 @@ func saveSessionStats(safeSession *econtext.SafeSession, stmtType sqlparser.Stat if !safeSession.IsFoundRowsHandled() { safeSession.FoundRows = uint64(rowsReturned) } - if insertID > 0 { - safeSession.LastInsertId = insertID - } switch stmtType { case sqlparser.StmtInsert, sqlparser.StmtReplace, sqlparser.StmtUpdate, sqlparser.StmtDelete: safeSession.RowCount = int64(rowsAffected) @@ -492,7 +490,7 @@ func (e *Executor) addNeededBindVars(vcursor *econtext.VCursorImpl, bindVarNeeds case sysvars.TransactionMode.Name: txMode := session.TransactionMode if txMode == vtgatepb.TransactionMode_UNSPECIFIED { - txMode = getTxMode() + txMode = transactionMode.Get() } bindVars[key] = sqltypes.StringBindVariable(txMode.String()) case sysvars.Workload.Name: @@ -679,7 +677,7 @@ func (e *Executor) executeSPInAllSessions(ctx context.Context, safeSession *econ }) queries = append(queries, &querypb.BoundQuery{Sql: sql}) } - qr, errs = e.ExecuteMultiShard(ctx, nil, rss, queries, safeSession, false /*autocommit*/, ignoreMaxMemoryRows, nullResultsObserver{}) + qr, errs = e.ExecuteMultiShard(ctx, nil, rss, queries, safeSession, false /*autocommit*/, ignoreMaxMemoryRows, nullResultsObserver{}, false) err := vterrors.Aggregate(errs) if err != nil { return nil, err @@ -1164,11 +1162,7 @@ func (e *Executor) buildStatement( reservedVars *sqlparser.ReservedVars, bindVarNeeds *sqlparser.BindVarNeeds, ) (*engine.Plan, error) { - cfg := &dynamicViperConfig{ - onlineDDL: enableOnlineDDL, - directDDL: enableDirectDDL, - } - plan, err := planbuilder.BuildFromStmt(ctx, query, stmt, reservedVars, vcursor, bindVarNeeds, cfg) + plan, err := planbuilder.BuildFromStmt(ctx, query, stmt, reservedVars, vcursor, bindVarNeeds, e.ddlConfig) if err != nil { return nil, err } @@ -1348,7 +1342,7 @@ func isValidPayloadSize(query string) bool { // Prepare executes a prepare statements. func (e *Executor) Prepare(ctx context.Context, method string, safeSession *econtext.SafeSession, sql string, bindVars map[string]*querypb.BindVariable) (fld []*querypb.Field, err error) { - logStats := logstats.NewLogStats(ctx, method, sql, safeSession.GetSessionUUID(), bindVars) + logStats := logstats.NewLogStats(ctx, method, sql, safeSession.GetSessionUUID(), bindVars, streamlog.GetQueryLogConfig()) fld, err = e.prepare(ctx, safeSession, sql, bindVars, logStats) logStats.Error = err @@ -1427,7 +1421,7 @@ func (e *Executor) initVConfig(warnOnShardedOnly bool, pv plancontext.PlannerVer DBDDLPlugin: dbDDLPlugin, - WarmingReadsPercent: e.warmingReadsPercent, + WarmingReadsPercent: e.config.WarmingReadsPercent, WarmingReadsTimeout: warmingReadsQueryTimeout, WarmingReadsChannel: e.warmingReadsChannel, } @@ -1485,13 +1479,13 @@ func parseAndValidateQuery(query string, parser *sqlparser.Parser) (sqlparser.St } // ExecuteMultiShard implements the IExecutor interface -func (e *Executor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *econtext.SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver econtext.ResultsObserver) (qr *sqltypes.Result, errs []error) { - return e.scatterConn.ExecuteMultiShard(ctx, primitive, rss, queries, session, autocommit, ignoreMaxMemoryRows, resultsObserver) +func (e *Executor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *econtext.SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver econtext.ResultsObserver, fetchLastInsertID bool) (qr *sqltypes.Result, errs []error) { + return e.scatterConn.ExecuteMultiShard(ctx, primitive, rss, queries, session, autocommit, ignoreMaxMemoryRows, resultsObserver, fetchLastInsertID) } // StreamExecuteMulti implements the IExecutor interface -func (e *Executor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *econtext.SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, resultsObserver econtext.ResultsObserver) []error { - return e.scatterConn.StreamExecuteMulti(ctx, primitive, query, rss, vars, session, autocommit, callback, resultsObserver) +func (e *Executor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *econtext.SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, resultsObserver econtext.ResultsObserver, fetchLastInsertID bool) []error { + return e.scatterConn.StreamExecuteMulti(ctx, primitive, query, rss, vars, session, autocommit, callback, resultsObserver, fetchLastInsertID) } // ExecuteLock implements the IExecutor interface @@ -1547,7 +1541,7 @@ func (e *Executor) startVStream(ctx context.Context, rss []*srvtopo.ResolvedShar } func (e *Executor) checkThatPlanIsValid(stmt sqlparser.Statement, plan *engine.Plan) error { - if e.allowScatter || plan.Instructions == nil || sqlparser.AllowScatterDirective(stmt) { + if e.config.AllowScatter || plan.Instructions == nil || sqlparser.AllowScatterDirective(stmt) { return nil } // we go over all the primitives in the plan, searching for a route that is of SelectScatter opcode @@ -1618,7 +1612,7 @@ func (e *Executor) PlanPrepareStmt(ctx context.Context, vcursor *econtext.VCurso } // creating this log stats to not interfere with the original log stats. - lStats := logstats.NewLogStats(ctx, "prepare", query, vcursor.Session().GetSessionUUID(), nil) + lStats := logstats.NewLogStats(ctx, "prepare", query, vcursor.Session().GetSessionUUID(), nil, streamlog.GetQueryLogConfig()) plan, err := e.getPlan( ctx, vcursor, diff --git a/go/vt/vtgate/executor_dml_test.go b/go/vt/vtgate/executor_dml_test.go index 792e197f48d..2846c763ae9 100644 --- a/go/vt/vtgate/executor_dml_test.go +++ b/go/vt/vtgate/executor_dml_test.go @@ -608,9 +608,8 @@ func TestUpdateComments(t *testing.T) { } func TestUpdateNormalize(t *testing.T) { - executor, sbc1, sbc2, _, ctx := createExecutorEnv(t) + executor, sbc1, sbc2, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) - executor.normalize = true session := &vtgatepb.Session{ TargetString: "@primary", } @@ -1337,7 +1336,7 @@ func TestInsertSharded(t *testing.T) { testQueryLog(t, executor, logChan, "TestExecute", "INSERT", "insert into user2(id, `name`, lastname) values (2, 'myname', 'mylastname')", 1) // insert with binary values - executor.normalize = true + executor.config.Normalize = true sbc1.Queries = nil sbc2.Queries = nil sbclookup.Queries = nil @@ -1368,8 +1367,7 @@ func TestInsertSharded(t *testing.T) { } func TestInsertNegativeValue(t *testing.T) { - executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -1812,8 +1810,9 @@ func TestInsertGeneratorSharded(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -1840,8 +1839,9 @@ func TestInsertGeneratorSharded(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, } utils.MustMatch(t, wantResult, result) } @@ -1854,8 +1854,9 @@ func TestInsertAutoincSharded(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 2, + RowsAffected: 1, + InsertID: 2, + InsertIDChanged: true, } sbc.SetResults([]*sqltypes.Result{wantResult}) session := &vtgatepb.Session{ @@ -1894,8 +1895,9 @@ func TestInsertGeneratorUnsharded(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } @@ -1912,8 +1914,9 @@ func TestInsertAutoincUnsharded(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 2, + RowsAffected: 1, + InsertID: 2, + InsertIDChanged: true, } sbclookup.SetResults([]*sqltypes.Result{wantResult}) @@ -1965,8 +1968,9 @@ func TestInsertLookupOwnedGenerator(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(4), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertID: 1, + InsertIDChanged: true, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -1993,8 +1997,9 @@ func TestInsertLookupOwnedGenerator(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 4, - RowsAffected: 1, + InsertID: 4, + InsertIDChanged: true, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } @@ -2226,8 +2231,9 @@ func TestMultiInsertGenerator(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -2258,8 +2264,9 @@ func TestMultiInsertGenerator(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } @@ -2271,8 +2278,9 @@ func TestMultiInsertGeneratorSparse(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -2307,8 +2315,9 @@ func TestMultiInsertGeneratorSparse(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } @@ -2517,9 +2526,7 @@ func TestDeleteEqualWithPrepare(t *testing.T) { } func TestUpdateLastInsertID(t *testing.T) { - executor, sbc1, _, _, ctx := createExecutorEnv(t) - - executor.normalize = true + executor, sbc1, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) sql := "update user set a = last_insert_id() where id = 1" session := &vtgatepb.Session{ diff --git a/go/vt/vtgate/executor_framework_test.go b/go/vt/vtgate/executor_framework_test.go index 2ee3425209f..099b785b446 100644 --- a/go/vt/vtgate/executor_framework_test.go +++ b/go/vt/vtgate/executor_framework_test.go @@ -65,10 +65,6 @@ var badVSchema = ` } ` -const ( - testBufferSize = 10 -) - type DestinationAnyShardPickerFirstShard struct{} func (dp DestinationAnyShardPickerFirstShard) PickShard(shardCount int) int { @@ -130,7 +126,7 @@ func init() { vindexes.Register("keyrange_lookuper_unique", newKeyRangeLookuperUnique) } -func createExecutorEnvCallback(t testing.TB, eachShard func(shard, ks string, tabletType topodatapb.TabletType, conn *sandboxconn.SandboxConn)) (executor *Executor, ctx context.Context) { +func createExecutorEnvCallback(t testing.TB, eConfig ExecutorConfig, eachShard func(shard, ks string, tabletType topodatapb.TabletType, conn *sandboxconn.SandboxConn)) (executor *Executor, ctx context.Context) { var cancel context.CancelFunc ctx, cancel = context.WithCancel(context.Background()) cell := "aa" @@ -183,7 +179,7 @@ func createExecutorEnvCallback(t testing.TB, eachShard func(shard, ks string, ta // one-off queries from thrashing the cache. Disable the doorkeeper in the tests to prevent flakiness. plans := theine.NewStore[PlanCacheKey, *engine.Plan](queryPlanCacheMemory, false) - executor = NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, false, false, testBufferSize, plans, nil, false, querypb.ExecuteOptions_Gen4, 0) + executor = NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, eConfig, false, plans, nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) executor.SetQueryLogger(queryLogger) key.AnyShardPicker = DestinationAnyShardPickerFirstShard{} @@ -198,7 +194,11 @@ func createExecutorEnvCallback(t testing.TB, eachShard func(shard, ks string, ta } func createExecutorEnv(t testing.TB) (executor *Executor, sbc1, sbc2, sbclookup *sandboxconn.SandboxConn, ctx context.Context) { - executor, ctx = createExecutorEnvCallback(t, func(shard, ks string, tabletType topodatapb.TabletType, conn *sandboxconn.SandboxConn) { + return createExecutorEnvWithConfig(t, createExecutorConfig()) +} + +func createExecutorEnvWithConfig(t testing.TB, eConfig ExecutorConfig) (executor *Executor, sbc1, sbc2, sbclookup *sandboxconn.SandboxConn, ctx context.Context) { + executor, ctx = createExecutorEnvCallback(t, eConfig, func(shard, ks string, tabletType topodatapb.TabletType, conn *sandboxconn.SandboxConn) { switch { case ks == KsTestSharded && shard == "-20": sbc1 = conn @@ -210,7 +210,6 @@ func createExecutorEnv(t testing.TB) (executor *Executor, sbc1, sbc2, sbclookup }) return } - func createCustomExecutor(t testing.TB, vschema string, mysqlVersion string) (executor *Executor, sbc1, sbc2, sbclookup *sandboxconn.SandboxConn, ctx context.Context) { var cancel context.CancelFunc ctx, cancel = context.WithCancel(context.Background()) @@ -232,7 +231,7 @@ func createCustomExecutor(t testing.TB, vschema string, mysqlVersion string) (ex plans := DefaultPlanCache() env, err := vtenv.New(vtenv.Options{MySQLServerVersion: mysqlVersion}) require.NoError(t, err) - executor = NewExecutor(ctx, env, serv, cell, resolver, false, false, testBufferSize, plans, nil, false, querypb.ExecuteOptions_Gen4, 0) + executor = NewExecutor(ctx, env, serv, cell, resolver, createExecutorConfig(), false, plans, nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) executor.SetQueryLogger(queryLogger) t.Cleanup(func() { @@ -244,6 +243,21 @@ func createCustomExecutor(t testing.TB, vschema string, mysqlVersion string) (ex return executor, sbc1, sbc2, sbclookup, ctx } +func createExecutorConfig() ExecutorConfig { + return ExecutorConfig{ + StreamSize: 10, + AllowScatter: true, + } +} + +func createExecutorConfigWithNormalizer() ExecutorConfig { + return ExecutorConfig{ + StreamSize: 10, + AllowScatter: true, + Normalize: true, + } +} + func createCustomExecutorSetValues(t testing.TB, vschema string, values []*sqltypes.Result) (executor *Executor, sbc1, sbc2, sbclookup *sandboxconn.SandboxConn, ctx context.Context) { var cancel context.CancelFunc ctx, cancel = context.WithCancel(context.Background()) @@ -269,7 +283,7 @@ func createCustomExecutorSetValues(t testing.TB, vschema string, values []*sqlty sbclookup = hc.AddTestTablet(cell, "0", 1, KsTestUnsharded, "0", topodatapb.TabletType_PRIMARY, true, 1, nil) queryLogger := streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize) plans := DefaultPlanCache() - executor = NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, false, false, testBufferSize, plans, nil, false, querypb.ExecuteOptions_Gen4, 0) + executor = NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, createExecutorConfig(), false, plans, nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) executor.SetQueryLogger(queryLogger) t.Cleanup(func() { @@ -294,7 +308,9 @@ func createExecutorEnvWithPrimaryReplicaConn(t testing.TB, ctx context.Context, replica = hc.AddTestTablet(cell, "0-replica", 1, KsTestUnsharded, "0", topodatapb.TabletType_REPLICA, true, 1, nil) queryLogger := streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize) - executor = NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, false, false, testBufferSize, DefaultPlanCache(), nil, false, querypb.ExecuteOptions_Gen4, warmingReadsPercent) + eConfig := createExecutorConfig() + eConfig.WarmingReadsPercent = warmingReadsPercent + executor = NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, eConfig, false, DefaultPlanCache(), nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) executor.SetQueryLogger(queryLogger) t.Cleanup(func() { diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 86aafaefba4..3d8261495fe 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -166,7 +166,7 @@ func TestSelectDBA(t *testing.T) { func TestSystemVariablesMySQLBelow80(t *testing.T) { executor, sbc1, _, _, _ := createCustomExecutor(t, "{}", "5.7.0") - executor.normalize = true + executor.config.Normalize = true setVarEnabled = true session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, TargetString: "TestExecutor"}) @@ -200,7 +200,7 @@ func TestSystemVariablesMySQLBelow80(t *testing.T) { func TestSystemVariablesWithSetVarDisabled(t *testing.T) { executor, sbc1, _, _, _ := createCustomExecutor(t, "{}", "8.0.0") - executor.normalize = true + executor.config.Normalize = true executor.vConfig.SetVarEnabled = false session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, TargetString: "TestExecutor"}) @@ -233,7 +233,7 @@ func TestSystemVariablesWithSetVarDisabled(t *testing.T) { func TestSetSystemVariablesTx(t *testing.T) { executor, sbc1, _, _, _ := createCustomExecutor(t, "{}", "8.0.1") - executor.normalize = true + executor.config.Normalize = true session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, TargetString: "TestExecutor"}) @@ -278,9 +278,7 @@ func TestSetSystemVariablesTx(t *testing.T) { } func TestSetSystemVariables(t *testing.T) { - executor, _, _, lookup, _ := createExecutorEnv(t) - executor.normalize = true - + executor, _, _, lookup, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, TargetString: KsTestUnsharded, SystemVariables: map[string]string{}}) // Set @@sql_mode and execute a select statement. We should have SET_VAR in the select statement @@ -389,8 +387,7 @@ func TestSetSystemVariables(t *testing.T) { } func TestSetSystemVariablesWithReservedConnection(t *testing.T) { - executor, sbc1, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, SystemVariables: map[string]string{}}) @@ -445,8 +442,7 @@ func TestSelectVindexFunc(t *testing.T) { } func TestCreateTableValidTimestamp(t *testing.T) { - executor, sbc1, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor", SystemVariables: map[string]string{"sql_mode": "ALLOW_INVALID_DATES"}}) @@ -464,8 +460,7 @@ func TestCreateTableValidTimestamp(t *testing.T) { } func TestGen4SelectDBA(t *testing.T) { - executor, sbc1, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) query := "select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS" _, err := executor.Execute(context.Background(), nil, "TestSelectDBA", @@ -699,18 +694,19 @@ func TestStreamLimitOffset(t *testing.T) { }}, } - executor, _ := createExecutorEnvCallback(t, func(shard, ks string, tabletType topodatapb.TabletType, conn *sandboxconn.SandboxConn) { - if ks == KsTestSharded { - conn.SetResults([]*sqltypes.Result{{ - Fields: []*querypb.Field{ - {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, - {Name: "textcol", Type: sqltypes.VarChar, Charset: uint32(collations.MySQL8().DefaultConnectionCharset())}, - {Name: "weight_string(id)", Type: sqltypes.VarBinary, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_BINARY_FLAG)}, - }, - Rows: returnRows[shard], - }}) - } - }) + executor, _ := createExecutorEnvCallback(t, createExecutorConfig(), + func(shard, ks string, tabletType topodatapb.TabletType, conn *sandboxconn.SandboxConn) { + if ks == KsTestSharded { + conn.SetResults([]*sqltypes.Result{{ + Fields: []*querypb.Field{ + {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "textcol", Type: sqltypes.VarChar, Charset: uint32(collations.MySQL8().DefaultConnectionCharset())}, + {Name: "weight_string(id)", Type: sqltypes.VarBinary, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_BINARY_FLAG)}, + }, + Rows: returnRows[shard], + }}) + } + }) results := make(chan *sqltypes.Result, 10) session := &vtgatepb.Session{ @@ -756,12 +752,11 @@ func TestStreamLimitOffset(t *testing.T) { } func TestSelectLastInsertId(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{ TargetString: "@primary", LastInsertId: 52, } - executor.normalize = true logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -780,7 +775,7 @@ func TestSelectLastInsertId(t *testing.T) { } func TestSelectSystemVariables(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{ TargetString: "@primary", @@ -790,7 +785,6 @@ func TestSelectSystemVariables(t *testing.T) { SessionTrackGtids: true, }, } - executor.normalize = true logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -840,8 +834,7 @@ func TestSelectSystemVariables(t *testing.T) { } func TestSelectInitializedVitessAwareVariable(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -872,8 +865,7 @@ func TestSelectInitializedVitessAwareVariable(t *testing.T) { } func TestSelectUserDefinedVariable(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -908,8 +900,7 @@ func TestSelectUserDefinedVariable(t *testing.T) { } func TestFoundRows(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -935,8 +926,7 @@ func TestFoundRows(t *testing.T) { } func TestRowCount(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -968,8 +958,7 @@ func testRowCount(t *testing.T, ctx context.Context, executor *Executor, session } func TestSelectLastInsertIdInUnion(t *testing.T) { - executor, sbc1, _, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{ TargetString: "@primary", @@ -1002,8 +991,7 @@ func TestSelectLastInsertIdInUnion(t *testing.T) { } func TestSelectLastInsertIdInWhere(t *testing.T) { - executor, _, _, lookup, ctx := createExecutorEnv(t) - executor.normalize = true + executor, _, _, lookup, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -1022,8 +1010,7 @@ func TestSelectLastInsertIdInWhere(t *testing.T) { } func TestLastInsertIDInVirtualTable(t *testing.T) { - executor, sbc1, _, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) result1 := []*sqltypes.Result{{ Fields: []*querypb.Field{ {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, @@ -1050,8 +1037,7 @@ func TestLastInsertIDInVirtualTable(t *testing.T) { } func TestLastInsertIDInSubQueryExpression(t *testing.T) { - executor, sbc1, sbc2, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{ TargetString: "@primary", LastInsertId: 12345, @@ -1074,8 +1060,7 @@ func TestLastInsertIDInSubQueryExpression(t *testing.T) { } func TestSelectDatabase(t *testing.T) { - executor, _, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) sql := "select database()" newSession := &vtgatepb.Session{ TargetString: "@primary", @@ -1334,8 +1319,7 @@ func TestSelectComments(t *testing.T) { } func TestSelectNormalize(t *testing.T) { - executor, sbc1, sbc2, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{ TargetString: "@primary", @@ -1644,7 +1628,7 @@ func TestSelectListArg(t *testing.T) { func createExecutor(ctx context.Context, serv *sandboxTopo, cell string, resolver *Resolver) *Executor { queryLogger := streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize) plans := DefaultPlanCache() - ex := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, false, false, testBufferSize, plans, nil, false, querypb.ExecuteOptions_Gen4, 0) + ex := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, createExecutorConfig(), false, plans, nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) ex.SetQueryLogger(queryLogger) return ex } @@ -3123,8 +3107,7 @@ func TestSelectBindvarswithPrepare(t *testing.T) { } func TestSelectDatabasePrepare(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -3137,8 +3120,7 @@ func TestSelectDatabasePrepare(t *testing.T) { } func TestSelectWithUnionAll(t *testing.T) { - executor, sbc1, sbc2, _, ctx := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) sql := "select id from user where id in (1, 2, 3) union all select id from user where id in (1, 2, 3)" bv, _ := sqltypes.BuildBindVariable([]int64{1, 2, 3}) bv1, _ := sqltypes.BuildBindVariable([]int64{1, 2}) @@ -3302,6 +3284,49 @@ func TestSelectFromInformationSchema(t *testing.T) { sbc1.StringQueries()) } +func TestStreamOrderByWithMultipleResults(t *testing.T) { + ctx := utils.LeakCheckContext(t) + + // Special setup: Don't use createExecutorEnv. + cell := "aa" + hc := discovery.NewFakeHealthCheck(nil) + u := createSandbox(KsTestUnsharded) + s := createSandbox(KsTestSharded) + s.VSchema = executorVSchema + u.VSchema = unshardedVSchema + serv := newSandboxForCells(ctx, []string{cell}) + resolver := newTestResolver(ctx, hc, serv, cell) + shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"} + count := 1 + for _, shard := range shards { + sbc := hc.AddTestTablet(cell, shard, 1, "TestExecutor", shard, topodatapb.TabletType_PRIMARY, true, 1, nil) + sbc.SetResults([]*sqltypes.Result{ + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col|weight_string(id)", "int32|int32|varchar"), fmt.Sprintf("%d|%d|NULL", count, count)), + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col|weight_string(id)", "int32|int32|varchar"), fmt.Sprintf("%d|%d|NULL", count+10, count)), + }) + count++ + } + queryLogger := streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize) + plans := DefaultPlanCache() + executor := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, createExecutorConfigWithNormalizer(), false, plans, nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) + executor.SetQueryLogger(queryLogger) + defer executor.Close() + // some sleep for all goroutines to start + time.Sleep(100 * time.Millisecond) + before := runtime.NumGoroutine() + + query := "select id, col from user order by id" + gotResult, err := executorStream(ctx, executor, query) + require.NoError(t, err) + + wantResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col", "int32|int32"), + "1|1", "2|2", "3|3", "4|4", "5|5", "6|6", "7|7", "8|8", "11|1", "12|2", "13|3", "14|4", "15|5", "16|6", "17|7", "18|8") + assert.Equal(t, fmt.Sprintf("%v", wantResult.Rows), fmt.Sprintf("%v", gotResult.Rows)) + // some sleep to close all goroutines. + time.Sleep(100 * time.Millisecond) + assert.GreaterOrEqual(t, before, runtime.NumGoroutine(), "left open goroutines lingering") +} + func TestStreamOrderByLimitWithMultipleResults(t *testing.T) { ctx := utils.LeakCheckContext(t) @@ -3326,7 +3351,7 @@ func TestStreamOrderByLimitWithMultipleResults(t *testing.T) { } queryLogger := streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize) plans := DefaultPlanCache() - executor := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, true, false, testBufferSize, plans, nil, false, querypb.ExecuteOptions_Gen4, 0) + executor := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, createExecutorConfigWithNormalizer(), false, plans, nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) executor.SetQueryLogger(queryLogger) defer executor.Close() // some sleep for all goroutines to start @@ -3377,7 +3402,7 @@ func TestSelectScatterFails(t *testing.T) { executor := createExecutor(ctx, serv, cell, resolver) defer executor.Close() - executor.allowScatter = false + executor.config.AllowScatter = false logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -3404,8 +3429,7 @@ func TestSelectScatterFails(t *testing.T) { } func TestGen4SelectStraightJoin(t *testing.T) { - executor, sbc1, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) query := "select u.id from user u straight_join user2 u2 on u.id = u2.id" @@ -3426,8 +3450,7 @@ func TestGen4SelectStraightJoin(t *testing.T) { } func TestGen4MultiColumnVindexEqual(t *testing.T) { - executor, sbc1, sbc2, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) query := "select * from user_region where cola = 1 and colb = 2" @@ -3464,8 +3487,7 @@ func TestGen4MultiColumnVindexEqual(t *testing.T) { } func TestGen4MultiColumnVindexIn(t *testing.T) { - executor, sbc1, sbc2, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) query := "select * from user_region where cola IN (1,17984) and colb IN (2,3,4)" @@ -3502,8 +3524,7 @@ func TestGen4MultiColumnVindexIn(t *testing.T) { } func TestGen4MultiColMixedColComparision(t *testing.T) { - executor, sbc1, sbc2, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) query := "select * from user_region where colb = 2 and cola IN (1,17984)" @@ -3538,8 +3559,7 @@ func TestGen4MultiColMixedColComparision(t *testing.T) { } func TestGen4MultiColBestVindexSel(t *testing.T) { - executor, sbc1, sbc2, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) query := "select * from user_region where colb = 2 and cola IN (1,17984) and cola = 1" @@ -3583,8 +3603,7 @@ func TestGen4MultiColBestVindexSel(t *testing.T) { } func TestGen4MultiColMultiEqual(t *testing.T) { - executor, sbc1, sbc2, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, sbc2, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) query := "select * from user_region where (cola,colb) in ((17984,2),(17984,3))" @@ -4186,8 +4205,7 @@ func TestSelectAggregationRandom(t *testing.T) { } func TestSelectDateTypes(t *testing.T) { - executor, _, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewAutocommitSession(&vtgatepb.Session{}) qr, err := executor.Execute(context.Background(), nil, "TestSelectDateTypes", session, "select '2020-01-01' + interval month(date_sub(FROM_UNIXTIME(1234), interval 1 month))-1 month", nil) @@ -4197,8 +4215,7 @@ func TestSelectDateTypes(t *testing.T) { } func TestSelectHexAndBit(t *testing.T) { - executor, _, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewAutocommitSession(&vtgatepb.Session{}) qr, err := executor.Execute(context.Background(), nil, "TestSelectHexAndBit", session, "select 0b1001, b'1001', 0x9, x'09'", nil) @@ -4213,8 +4230,7 @@ func TestSelectHexAndBit(t *testing.T) { // TestSelectCFC tests validates that cfc vindex plan gets cached and same plan is getting reused. // This also validates that cache_size is able to calculate the cfc vindex plan size. func TestSelectCFC(t *testing.T) { - executor, _, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, _, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewAutocommitSession(&vtgatepb.Session{}) _, err := executor.Execute(context.Background(), nil, "TestSelectCFC", session, "select /*vt+ PLANNER=gen4 */ c2 from tbl_cfc where c1 like 'A%'", nil) @@ -4238,12 +4254,11 @@ func TestSelectCFC(t *testing.T) { } func TestSelectView(t *testing.T) { - executor, sbc, _, _, _ := createExecutorEnv(t) + executor, sbc, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) // add the view to local vschema err := executor.vschema.AddView(KsTestSharded, "user_details_view", "select user.id, user_extra.col from user join user_extra on user.id = user_extra.user_id", executor.vm.parser) require.NoError(t, err) - executor.normalize = true session := econtext.NewAutocommitSession(&vtgatepb.Session{}) _, err = executor.Execute(context.Background(), nil, "TestSelectView", session, "select * from user_details_view", nil) @@ -4284,7 +4299,7 @@ func TestWarmingReads(t *testing.T) { ctx := utils.LeakCheckContext(t) executor, primary, replica := createExecutorEnvWithPrimaryReplicaConn(t, ctx, 100) - executor.normalize = true + executor.config.Normalize = true session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: KsTestUnsharded}) // Since queries on the replica will run in a separate go-routine, we need synchronization for the Queries field in the sandboxconn. replica.RequireQueriesLocking() @@ -4408,8 +4423,7 @@ func TestStreamJoinQuery(t *testing.T) { // It also tests that setting a global variable does not affect the session variable and vice versa. // Also, test what happens on running select @@global and select @@session for a system variable. func TestSysVarGlobalAndSession(t *testing.T) { - executor, sbc1, _, _, _ := createExecutorEnv(t) - executor.normalize = true + executor, sbc1, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, SystemVariables: map[string]string{}}) sbc1.SetResults([]*sqltypes.Result{ diff --git a/go/vt/vtgate/executor_set_test.go b/go/vt/vtgate/executor_set_test.go index 62101639a11..310d885a134 100644 --- a/go/vt/vtgate/executor_set_test.go +++ b/go/vt/vtgate/executor_set_test.go @@ -401,9 +401,9 @@ func TestExecutorSetMetadata(t *testing.T) { }) t.Run("Session 2", func(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) @@ -411,11 +411,11 @@ func TestExecutorSetMetadata(t *testing.T) { set := "set @@vitess_metadata.app_keyspace_v1= '1'" _, err := executor.Execute(ctx, nil, "TestExecute", session, set, nil) - assert.NoError(t, err, "%s error: %v", set, err) + require.NoError(t, err, "%s error: %v", set, err) show := `show vitess_metadata variables like 'app\\_keyspace\\_v_'` result, err := executor.Execute(ctx, nil, "TestExecute", session, show, nil) - assert.NoError(t, err) + require.NoError(t, err) want := "1" got := result.Rows[0][1].ToString() @@ -424,11 +424,11 @@ func TestExecutorSetMetadata(t *testing.T) { // Update metadata set = "set @@vitess_metadata.app_keyspace_v2='2'" _, err = executor.Execute(ctx, nil, "TestExecute", session, set, nil) - assert.NoError(t, err, "%s error: %v", set, err) + require.NoError(t, err, "%s error: %v", set, err) show = `show vitess_metadata variables like 'app\\_keyspace\\_v%'` gotqr, err := executor.Execute(ctx, nil, "TestExecute", session, show, nil) - assert.NoError(t, err) + require.NoError(t, err) wantqr := &sqltypes.Result{ Fields: buildVarCharFields("Key", "Value"), @@ -514,7 +514,7 @@ func createMap(keys []string, values []any) map[string]*querypb.BindVariable { func TestSetVar(t *testing.T) { executor, _, _, sbc, ctx := createCustomExecutor(t, "{}", "8.0.0") - executor.normalize = true + executor.config.Normalize = true session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, TargetString: KsTestUnsharded}) @@ -553,7 +553,7 @@ func TestSetVar(t *testing.T) { func TestSetVarShowVariables(t *testing.T) { executor, _, _, sbc, ctx := createCustomExecutor(t, "{}", "8.0.0") - executor.normalize = true + executor.config.Normalize = true session := econtext.NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true, TargetString: KsTestUnsharded}) @@ -576,8 +576,7 @@ func TestSetVarShowVariables(t *testing.T) { } func TestExecutorSetAndSelect(t *testing.T) { - e, _, _, sbc, ctx := createExecutorEnv(t) - e.normalize = true + e, _, _, sbc, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) testcases := []struct { sysVar string diff --git a/go/vt/vtgate/executor_stream_test.go b/go/vt/vtgate/executor_stream_test.go index a8500dd59c4..796e0c0466b 100644 --- a/go/vt/vtgate/executor_stream_test.go +++ b/go/vt/vtgate/executor_stream_test.go @@ -68,7 +68,7 @@ func TestStreamSQLSharded(t *testing.T) { queryLogger := streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize) plans := DefaultPlanCache() - executor := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, false, false, testBufferSize, plans, nil, false, querypb.ExecuteOptions_Gen4, 0) + executor := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, createExecutorConfig(), false, plans, nil, querypb.ExecuteOptions_Gen4, NewDynamicViperConfig()) executor.SetQueryLogger(queryLogger) defer executor.Close() diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 2b6d4710bce..904805e789b 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -36,6 +36,8 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" + "vitess.io/vitess/go/streamlog" + econtext "vitess.io/vitess/go/vt/vtgate/executorcontext" "vitess.io/vitess/go/mysql/collations" @@ -196,9 +198,7 @@ func TestExecutorTransactionsNoAutoCommit(t *testing.T) { } func TestDirectTargetRewrites(t *testing.T) { - executor, _, _, sbclookup, ctx := createExecutorEnv(t) - - executor.normalize = true + executor, _, _, sbclookup, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{ TargetString: "TestUnsharded/0@primary", @@ -335,9 +335,9 @@ func TestExecutorTransactionsAutoCommitStreaming(t *testing.T) { } func TestExecutorDeleteMetadata(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) @@ -1277,17 +1277,19 @@ func TestExecutorDDL(t *testing.T) { } for _, stmt := range stmts2 { - sbc1.ExecCount.Store(0) - sbc2.ExecCount.Store(0) - sbclookup.ExecCount.Store(0) - _, err := executor.Execute(ctx, nil, "TestExecute", econtext.NewSafeSession(&vtgatepb.Session{TargetString: ""}), stmt.input, nil) - if stmt.hasErr { - require.EqualError(t, err, econtext.ErrNoKeyspace.Error(), "expect query to fail") - testQueryLog(t, executor, logChan, "TestExecute", "", stmt.input, 0) - } else { - require.NoError(t, err) - testQueryLog(t, executor, logChan, "TestExecute", "DDL", stmt.input, 8) - } + t.Run(stmt.input, func(t *testing.T) { + sbc1.ExecCount.Store(0) + sbc2.ExecCount.Store(0) + sbclookup.ExecCount.Store(0) + _, err := executor.Execute(ctx, nil, "TestExecute", econtext.NewSafeSession(&vtgatepb.Session{TargetString: ""}), stmt.input, nil) + if stmt.hasErr { + assert.EqualError(t, err, econtext.ErrNoKeyspace.Error(), "expect query to fail") + testQueryLog(t, executor, logChan, "TestExecute", "", stmt.input, 0) + } else { + assert.NoError(t, err) + testQueryLog(t, executor, logChan, "TestExecute", "DDL", stmt.input, 8) + } + }) } } @@ -1318,9 +1320,9 @@ func TestExecutorDDLFk(t *testing.T) { } func TestExecutorAlterVSchemaKeyspace(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) @@ -1347,9 +1349,9 @@ func TestExecutorAlterVSchemaKeyspace(t *testing.T) { } func TestExecutorCreateVindexDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t) ks := "TestExecutor" @@ -1417,9 +1419,9 @@ func TestExecutorCreateVindexDDL(t *testing.T) { } func TestExecutorAddDropVschemaTableDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t) ks := KsTestUnsharded @@ -1486,8 +1488,7 @@ func TestExecutorVindexDDLACL(t *testing.T) { require.EqualError(t, err, `User 'blueUser' is not authorized to perform vschema operations`) // test when all users are enabled - vschemaacl.AuthorizedDDLUsers = "%" - vschemaacl.Init() + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) _, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil) if err != nil { t.Errorf("unexpected error '%v'", err) @@ -1499,8 +1500,7 @@ func TestExecutorVindexDDLACL(t *testing.T) { } // test when only one user is enabled - vschemaacl.AuthorizedDDLUsers = "orangeUser, blueUser, greenUser" - vschemaacl.Init() + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("orangeUser, blueUser, greenUser")) _, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil) require.EqualError(t, err, `User 'redUser' is not authorized to perform vschema operations`) @@ -1511,7 +1511,7 @@ func TestExecutorVindexDDLACL(t *testing.T) { } // restore the disallowed state - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) } func TestExecutorUnrecognized(t *testing.T) { @@ -1625,7 +1625,7 @@ func assertCacheContains(t *testing.T, e *Executor, vc *econtext.VCursorImpl, sq } func getPlanCached(t *testing.T, ctx context.Context, e *Executor, vcursor *econtext.VCursorImpl, sql string, comments sqlparser.MarginComments, bindVars map[string]*querypb.BindVariable, skipQueryPlanCache bool) (*engine.Plan, *logstats.LogStats) { - logStats := logstats.NewLogStats(ctx, "Test", "", "", nil) + logStats := logstats.NewLogStats(ctx, "Test", "", "", nil, streamlog.NewQueryLogConfigForTest()) vcursor.SafeSession = &econtext.SafeSession{ Session: &vtgatepb.Session{ Options: &querypb.ExecuteOptions{SkipQueryPlanCache: skipQueryPlanCache}}, @@ -1633,7 +1633,7 @@ func getPlanCached(t *testing.T, ctx context.Context, e *Executor, vcursor *econ stmt, reservedVars, err := parseAndValidateQuery(sql, sqlparser.NewTestParser()) require.NoError(t, err) - plan, err := e.getPlan(context.Background(), vcursor, sql, stmt, comments, bindVars, reservedVars /* normalize */, e.normalize, logStats) + plan, err := e.getPlan(context.Background(), vcursor, sql, stmt, comments, bindVars, reservedVars /* normalize */, e.config.Normalize, logStats) require.NoError(t, err) // Wait for cache to settle @@ -1693,8 +1693,7 @@ func TestGetPlanCacheUnnormalized(t *testing.T) { func TestGetPlanCacheNormalized(t *testing.T) { t.Run("Cache", func(t *testing.T) { - r, _, _, _, ctx := createExecutorEnv(t) - r.normalize = true + r, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) emptyvc, _ := econtext.NewVCursorImpl(econtext.NewSafeSession(&vtgatepb.Session{TargetString: "@unknown"}), makeComments(""), r, nil, r.vm, r.VSchema(), r.resolver.resolver, nil, nullResultsObserver{}, r.vConfig) query1 := "select * from music_user_map where id = 1" @@ -1710,8 +1709,7 @@ func TestGetPlanCacheNormalized(t *testing.T) { t.Run("Skip Cache", func(t *testing.T) { // Skip cache using directive - r, _, _, _, ctx := createExecutorEnv(t) - r.normalize = true + r, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) unshardedvc, _ := econtext.NewVCursorImpl(econtext.NewSafeSession(&vtgatepb.Session{TargetString: KsTestUnsharded + "@unknown"}), makeComments(""), r, nil, r.vm, r.VSchema(), r.resolver.resolver, nil, nullResultsObserver{}, r.vConfig) query1 := "insert /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ into user(id) values (1), (2)" @@ -1735,9 +1733,8 @@ func TestGetPlanCacheNormalized(t *testing.T) { } func TestGetPlanNormalized(t *testing.T) { - r, _, _, _, ctx := createExecutorEnv(t) + r, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) - r.normalize = true emptyvc, _ := econtext.NewVCursorImpl(econtext.NewSafeSession(&vtgatepb.Session{TargetString: "@unknown"}), makeComments(""), r, nil, r.vm, r.VSchema(), r.resolver.resolver, nil, nullResultsObserver{}, econtext.VCursorConfig{}) unshardedvc, _ := econtext.NewVCursorImpl(econtext.NewSafeSession(&vtgatepb.Session{TargetString: KsTestUnsharded + "@unknown"}), makeComments(""), r, nil, r.vm, r.VSchema(), r.resolver.resolver, nil, nullResultsObserver{}, econtext.VCursorConfig{}) @@ -1792,10 +1789,9 @@ func TestGetPlanPriority(t *testing.T) { testCase := aTestCase t.Run(testCase.name, func(t *testing.T) { - r, _, _, _, ctx := createExecutorEnv(t) + r, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) - r.normalize = true - logStats := logstats.NewLogStats(ctx, "Test", "", "", nil) + logStats := logstats.NewLogStats(ctx, "Test", "", "", nil, streamlog.NewQueryLogConfigForTest()) vCursor, err := econtext.NewVCursorImpl(session, makeComments(""), r, nil, r.vm, r.VSchema(), r.resolver.resolver, nil, nullResultsObserver{}, econtext.VCursorConfig{}) assert.NoError(t, err) @@ -1818,7 +1814,7 @@ func TestGetPlanPriority(t *testing.T) { } func TestPassthroughDDL(t *testing.T) { - executor, sbc1, sbc2, _, ctx := createExecutorEnv(t) + executor, sbc1, sbc2, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{ TargetString: "TestExecutor", } @@ -1841,7 +1837,6 @@ func TestPassthroughDDL(t *testing.T) { // Force the query to go to only one shard. Normalization doesn't make any difference. session.TargetString = "TestExecutor/40-60" - executor.normalize = true _, err = executorExec(ctx, executor, session, alterDDL, nil) require.NoError(t, err) @@ -1853,7 +1848,6 @@ func TestPassthroughDDL(t *testing.T) { // Use range query session.TargetString = "TestExecutor[-]" - executor.normalize = true _, err = executorExec(ctx, executor, session, alterDDL, nil) require.NoError(t, err) @@ -2003,10 +1997,7 @@ func TestExecutorMaxPayloadSizeExceeded(t *testing.T) { } func TestOlapSelectDatabase(t *testing.T) { - executor, _, _, _, _ := createExecutorEnv(t) - - executor.normalize = true - + executor, _, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := &vtgatepb.Session{Autocommit: true} sql := `select database()` @@ -2284,9 +2275,7 @@ func TestExecutorExplainStmt(t *testing.T) { } func TestExecutorVExplain(t *testing.T) { - executor, _, _, _, ctx := createExecutorEnv(t) - - executor.normalize = true + executor, _, _, _, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) logChan := executor.queryLogger.Subscribe("Test") defer executor.queryLogger.Unsubscribe(logChan) @@ -2674,10 +2663,12 @@ func TestExecutorShowVitessMigrations(t *testing.T) { func TestExecutorDescHash(t *testing.T) { executor, _, _, _, ctx := createExecutorEnv(t) - - showQuery := "desc hash_index" session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) - _, err := executor.Execute(ctx, nil, "", session, showQuery, nil) + + _, err := executor.Execute(ctx, nil, "", session, "desc hash_index", nil) + require.EqualError(t, err, "VT05004: table 'hash_index' does not exist") + + _, err = executor.Execute(ctx, nil, "", session, "desc music", nil) require.NoError(t, err) } @@ -2754,9 +2745,7 @@ func TestExecutorStartTxnStmt(t *testing.T) { } func TestExecutorPrepareExecute(t *testing.T) { - executor, _, _, _, _ := createExecutorEnv(t) - - executor.normalize = true + executor, _, _, _, _ := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) session := econtext.NewAutocommitSession(&vtgatepb.Session{}) // prepare statement. @@ -2864,57 +2853,6 @@ func TestExecutorSettingsInTwoPC(t *testing.T) { } } -// TestExecutorRejectTwoPC test all the unsupported cases for multi-shard atomic commit. -func TestExecutorRejectTwoPC(t *testing.T) { - executor, sbc1, sbc2, _, ctx := createExecutorEnv(t) - tcases := []struct { - sqls []string - testRes []*sqltypes.Result - - expErr string - }{ - { - sqls: []string{ - `update t1 set unq_col = 1 where id = 1`, - `update t1 set unq_col = 1 where id = 3`, - }, - testRes: []*sqltypes.Result{ - sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|unq_col|unchanged", "int64|int64|int64"), - "1|2|0"), - }, - expErr: "VT12001: unsupported: atomic distributed transaction commit with consistent lookup vindex", - }, - } - - for _, tcase := range tcases { - t.Run(fmt.Sprintf("%v", tcase.sqls), func(t *testing.T) { - sbc1.SetResults(tcase.testRes) - sbc2.SetResults(tcase.testRes) - - // create a new session - session := econtext.NewSafeSession(&vtgatepb.Session{ - TargetString: KsTestSharded, - TransactionMode: vtgatepb.TransactionMode_TWOPC, - EnableSystemSettings: true, - }) - - // start transaction - _, err := executor.Execute(ctx, nil, "TestExecutorRejectTwoPC", session, "begin", nil) - require.NoError(t, err) - - // execute queries - for _, sql := range tcase.sqls { - _, err = executor.Execute(ctx, nil, "TestExecutorRejectTwoPC", session, sql, nil) - require.NoError(t, err) - } - - // commit 2pc - _, err = executor.Execute(ctx, nil, "TestExecutorRejectTwoPC", session, "commit", nil) - require.ErrorContains(t, err, tcase.expErr) - }) - } -} - func TestExecutorTruncateErrors(t *testing.T) { executor, _, _, _, ctx := createExecutorEnv(t) diff --git a/go/vt/vtgate/executor_vschema_ddl_test.go b/go/vt/vtgate/executor_vschema_ddl_test.go index 825b65ab8f3..1acc1ba2362 100644 --- a/go/vt/vtgate/executor_vschema_ddl_test.go +++ b/go/vt/vtgate/executor_vschema_ddl_test.go @@ -135,9 +135,9 @@ func waitForColVindexes(t *testing.T, ks, table string, names []string, executor } func TestPlanExecutorAlterVSchemaKeyspace(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "@primary", Autocommit: true}) @@ -163,9 +163,9 @@ func TestPlanExecutorAlterVSchemaKeyspace(t *testing.T) { } func TestPlanExecutorCreateVindexDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) ks := "TestExecutor" @@ -205,9 +205,9 @@ func TestPlanExecutorCreateVindexDDL(t *testing.T) { } func TestPlanExecutorDropVindexDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) ks := "TestExecutor" @@ -274,9 +274,9 @@ func TestPlanExecutorDropVindexDDL(t *testing.T) { } func TestPlanExecutorAddDropVschemaTableDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t) ks := KsTestUnsharded @@ -331,9 +331,9 @@ func TestPlanExecutorAddDropVschemaTableDDL(t *testing.T) { } func TestExecutorAddSequenceDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) ks := KsTestUnsharded @@ -391,9 +391,9 @@ func TestExecutorAddSequenceDDL(t *testing.T) { } func TestExecutorDropSequenceDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) ks := KsTestUnsharded @@ -442,9 +442,9 @@ func TestExecutorDropSequenceDDL(t *testing.T) { } func TestExecutorDropAutoIncDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, _, _, _, ctx := createExecutorEnv(t) ks := KsTestUnsharded @@ -484,9 +484,9 @@ func TestExecutorDropAutoIncDDL(t *testing.T) { } func TestExecutorAddDropVindexDDL(t *testing.T) { - vschemaacl.AuthorizedDDLUsers = "%" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) defer func() { - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) }() executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t) ks := "TestExecutor" @@ -747,8 +747,7 @@ func TestPlanExecutorVindexDDLACL(t *testing.T) { require.EqualError(t, err, `User 'blueUser' is not authorized to perform vschema operations`) // test when all users are enabled - vschemaacl.AuthorizedDDLUsers = "%" - vschemaacl.Init() + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%")) _, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil) if err != nil { t.Errorf("unexpected error '%v'", err) @@ -760,8 +759,7 @@ func TestPlanExecutorVindexDDLACL(t *testing.T) { } // test when only one user is enabled - vschemaacl.AuthorizedDDLUsers = "orangeUser, blueUser, greenUser" - vschemaacl.Init() + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("orangeUser, blueUser, greenUser")) _, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil) require.EqualError(t, err, `User 'redUser' is not authorized to perform vschema operations`) @@ -772,5 +770,5 @@ func TestPlanExecutorVindexDDLACL(t *testing.T) { } // restore the disallowed state - vschemaacl.AuthorizedDDLUsers = "" + vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("")) } diff --git a/go/vt/vtgate/executorcontext/safe_session.go b/go/vt/vtgate/executorcontext/safe_session.go index c77bba76ff8..e9a25438bc4 100644 --- a/go/vt/vtgate/executorcontext/safe_session.go +++ b/go/vt/vtgate/executorcontext/safe_session.go @@ -656,17 +656,18 @@ func (session *SafeSession) TimeZone() *time.Location { session.mu.Unlock() if !ok { - return nil + return time.Local } tz, err := sqltypes.DecodeStringSQL(zoneSQL) if err != nil { - return nil + return time.Local } - loc, _ := datetime.ParseTimeZone(tz) - // it's safe to ignore the error - if we get an error, loc will be nil, - // and this is exactly the behaviour we want anyway + loc, err := datetime.ParseTimeZone(tz) + if err != nil { + return time.Local + } return loc } diff --git a/go/vt/vtgate/executorcontext/safe_session_test.go b/go/vt/vtgate/executorcontext/safe_session_test.go index 14ea2ad9dac..66130209d33 100644 --- a/go/vt/vtgate/executorcontext/safe_session_test.go +++ b/go/vt/vtgate/executorcontext/safe_session_test.go @@ -173,6 +173,10 @@ func TestTimeZone(t *testing.T) { tz string want string }{ + { + tz: "", + want: time.Local.String(), + }, { tz: "'Europe/Amsterdam'", want: "Europe/Amsterdam", @@ -183,16 +187,18 @@ func TestTimeZone(t *testing.T) { }, { tz: "foo", - want: (*time.Location)(nil).String(), + want: time.Local.String(), }, } for _, tc := range testCases { t.Run(tc.tz, func(t *testing.T) { + sysvars := map[string]string{} + if tc.tz != "" { + sysvars["time_zone"] = tc.tz + } session := NewSafeSession(&vtgatepb.Session{ - SystemVariables: map[string]string{ - "time_zone": tc.tz, - }, + SystemVariables: sysvars, }) assert.Equal(t, tc.want, session.TimeZone().String()) diff --git a/go/vt/vtgate/executorcontext/vcursor_impl.go b/go/vt/vtgate/executorcontext/vcursor_impl.go index c1f341b38cf..4d3f631bac5 100644 --- a/go/vt/vtgate/executorcontext/vcursor_impl.go +++ b/go/vt/vtgate/executorcontext/vcursor_impl.go @@ -22,6 +22,7 @@ import ( "io" "sort" "strings" + "sync" "sync/atomic" "time" @@ -95,8 +96,8 @@ type ( // vcursor_impl needs these facilities to be able to be able to execute queries for vindexes iExecute interface { Execute(ctx context.Context, mysqlCtx vtgateservice.MySQLConnection, method string, session *SafeSession, s string, vars map[string]*querypb.BindVariable) (*sqltypes.Result, error) - ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver) (qr *sqltypes.Result, errs []error) - StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver) []error + ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver, fetchLastInsertID bool) (qr *sqltypes.Result, errs []error) + StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver, fetchLastInsertID bool) []error ExecuteLock(ctx context.Context, rs *srvtopo.ResolvedShard, query *querypb.BoundQuery, session *SafeSession, lockFuncType sqlparser.LockingFuncType) (*sqltypes.Result, error) Commit(ctx context.Context, safeSession *SafeSession) error ExecuteMessageStream(ctx context.Context, rss []*srvtopo.ResolvedShard, name string, callback func(*sqltypes.Result) error) error @@ -122,7 +123,7 @@ type ( // VSchemaOperator is an interface to Vschema Operations VSchemaOperator interface { GetCurrentSrvVschema() *vschemapb.SrvVSchema - UpdateVSchema(ctx context.Context, ksName string, vschema *vschemapb.SrvVSchema) error + UpdateVSchema(ctx context.Context, ks *topo.KeyspaceVSchemaInfo, vschema *vschemapb.SrvVSchema) error } // VCursorImpl implements the VCursor functionality used by dependent @@ -154,6 +155,8 @@ type ( observer ResultsObserver + // this protects the interOpStats and shardsStats fields from concurrent writes + mu sync.Mutex // this is a map of the number of rows that every primitive has returned // if this field is nil, it means that we are not logging operator traffic interOpStats map[engine.Primitive]engine.RowsReceived @@ -389,7 +392,7 @@ func (vc *VCursorImpl) StartPrimitiveTrace() func() engine.Stats { // FindTable finds the specified table. If the keyspace what specified in the input, it gets used as qualifier. // Otherwise, the keyspace from the request is used, if one was provided. func (vc *VCursorImpl) FindTable(name sqlparser.TableName) (*vindexes.Table, string, topodatapb.TabletType, key.Destination, error) { - destKeyspace, destTabletType, dest, err := vc.ParseDestinationTarget(name.Qualifier.String()) + destKeyspace, destTabletType, dest, err := vc.parseDestinationTarget(name.Qualifier.String()) if err != nil { return nil, "", destTabletType, nil, err } @@ -403,8 +406,8 @@ func (vc *VCursorImpl) FindTable(name sqlparser.TableName) (*vindexes.Table, str return table, destKeyspace, destTabletType, dest, err } -func (vc *VCursorImpl) FindView(name sqlparser.TableName) sqlparser.SelectStatement { - ks, _, _, err := vc.ParseDestinationTarget(name.Qualifier.String()) +func (vc *VCursorImpl) FindView(name sqlparser.TableName) sqlparser.TableStatement { + ks, _, _, err := vc.parseDestinationTarget(name.Qualifier.String()) if err != nil { return nil } @@ -415,7 +418,7 @@ func (vc *VCursorImpl) FindView(name sqlparser.TableName) sqlparser.SelectStatem } func (vc *VCursorImpl) FindRoutedTable(name sqlparser.TableName) (*vindexes.Table, error) { - destKeyspace, destTabletType, _, err := vc.ParseDestinationTarget(name.Qualifier.String()) + destKeyspace, destTabletType, _, err := vc.parseDestinationTarget(name.Qualifier.String()) if err != nil { return nil, err } @@ -439,7 +442,7 @@ func (vc *VCursorImpl) FindTableOrVindex(name sqlparser.TableName) (*vindexes.Ta return vc.getDualTable() } - destKeyspace, destTabletType, dest, err := ParseDestinationTarget(name.Qualifier.String(), vc.tabletType, vc.vschema) + destKeyspace, destTabletType, dest, err := vc.parseDestinationTarget(name.Qualifier.String()) if err != nil { return nil, nil, "", destTabletType, nil, err } @@ -453,7 +456,24 @@ func (vc *VCursorImpl) FindTableOrVindex(name sqlparser.TableName) (*vindexes.Ta return table, vindex, destKeyspace, destTabletType, dest, nil } -func (vc *VCursorImpl) ParseDestinationTarget(targetString string) (string, topodatapb.TabletType, key.Destination, error) { +// FindViewTarget finds the specified view's target keyspace. +func (vc *VCursorImpl) FindViewTarget(name sqlparser.TableName) (*vindexes.Keyspace, error) { + destKeyspace, _, _, err := vc.parseDestinationTarget(name.Qualifier.String()) + if err != nil { + return nil, err + } + if destKeyspace != "" { + return vc.FindKeyspace(destKeyspace) + } + + tbl, err := vc.vschema.FindRoutedTable("", name.Name.String(), vc.tabletType) + if err != nil || tbl == nil { + return nil, err + } + return tbl.Keyspace, nil +} + +func (vc *VCursorImpl) parseDestinationTarget(targetString string) (string, topodatapb.TabletType, key.Destination, error) { return ParseDestinationTarget(targetString, vc.tabletType, vc.vschema) } @@ -642,21 +662,29 @@ func (vc *VCursorImpl) ExecutePrimitive(ctx context.Context, primitive engine.Pr } func (vc *VCursorImpl) logOpTraffic(primitive engine.Primitive, res *sqltypes.Result) { - if vc.interOpStats != nil { - rows := vc.interOpStats[primitive] - if res == nil { - rows = append(rows, 0) - } else { - rows = append(rows, len(res.Rows)) - } - vc.interOpStats[primitive] = rows + if vc.interOpStats == nil { + return + } + + vc.mu.Lock() + defer vc.mu.Unlock() + + rows := vc.interOpStats[primitive] + if res == nil { + rows = append(rows, 0) + } else { + rows = append(rows, len(res.Rows)) } + vc.interOpStats[primitive] = rows } func (vc *VCursorImpl) logShardsQueried(primitive engine.Primitive, shardsNb int) { - if vc.shardsStats != nil { - vc.shardsStats[primitive] += engine.ShardsQueried(shardsNb) + if vc.shardsStats == nil { + return } + vc.mu.Lock() + defer vc.mu.Unlock() + vc.shardsStats[primitive] += engine.ShardsQueried(shardsNb) } func (vc *VCursorImpl) ExecutePrimitiveStandalone(ctx context.Context, primitive engine.Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { @@ -675,12 +703,20 @@ func (vc *VCursorImpl) ExecutePrimitiveStandalone(ctx context.Context, primitive func (vc *VCursorImpl) wrapCallback(callback func(*sqltypes.Result) error, primitive engine.Primitive) func(*sqltypes.Result) error { if vc.interOpStats == nil { - return callback + return func(r *sqltypes.Result) error { + if r.InsertIDUpdated() { + vc.SafeSession.LastInsertId = r.InsertID + } + return callback(r) + } } - return func(result *sqltypes.Result) error { - vc.logOpTraffic(primitive, result) - return callback(result) + return func(r *sqltypes.Result) error { + if r.InsertIDUpdated() { + vc.SafeSession.LastInsertId = r.InsertID + } + vc.logOpTraffic(primitive, r) + return callback(r) } } @@ -753,7 +789,7 @@ func (vc *VCursorImpl) markSavepoint(ctx context.Context, needsRollbackOnParialE } // ExecuteMultiShard is part of the engine.VCursor interface. -func (vc *VCursorImpl) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { +func (vc *VCursorImpl) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) { noOfShards := len(rss) atomic.AddUint64(&vc.logStats.ShardQueries, uint64(noOfShards)) err := vc.markSavepoint(ctx, rollbackOnError && (noOfShards > 1), map[string]*querypb.BindVariable{}) @@ -761,14 +797,17 @@ func (vc *VCursorImpl) ExecuteMultiShard(ctx context.Context, primitive engine.P return nil, []error{err} } - qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, commentedShardQueries(queries, vc.marginComments), vc.SafeSession, canAutocommit, vc.ignoreMaxMemoryRows, vc.observer) + qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, commentedShardQueries(queries, vc.marginComments), vc.SafeSession, canAutocommit, vc.ignoreMaxMemoryRows, vc.observer, fetchLastInsertID) vc.setRollbackOnPartialExecIfRequired(len(errs) != len(rss), rollbackOnError) vc.logShardsQueried(primitive, len(rss)) + if qr != nil && qr.InsertIDUpdated() { + vc.SafeSession.LastInsertId = qr.InsertID + } return qr, errs } // StreamExecuteMulti is the streaming version of ExecuteMultiShard. -func (vc *VCursorImpl) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error { +func (vc *VCursorImpl) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error { callback = vc.wrapCallback(callback, primitive) noOfShards := len(rss) @@ -778,7 +817,7 @@ func (vc *VCursorImpl) StreamExecuteMulti(ctx context.Context, primitive engine. return []error{err} } - errs := vc.executor.StreamExecuteMulti(ctx, primitive, vc.marginComments.Leading+query+vc.marginComments.Trailing, rss, bindVars, vc.SafeSession, autocommit, callback, vc.observer) + errs := vc.executor.StreamExecuteMulti(ctx, primitive, vc.marginComments.Leading+query+vc.marginComments.Trailing, rss, bindVars, vc.SafeSession, autocommit, callback, vc.observer, fetchLastInsertID) vc.setRollbackOnPartialExecIfRequired(len(errs) != len(rss), rollbackOnError) return errs @@ -791,7 +830,7 @@ func (vc *VCursorImpl) ExecuteLock(ctx context.Context, rs *srvtopo.ResolvedShar } // ExecuteStandalone is part of the engine.VCursor interface. -func (vc *VCursorImpl) ExecuteStandalone(ctx context.Context, primitive engine.Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { +func (vc *VCursorImpl) ExecuteStandalone(ctx context.Context, primitive engine.Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) { rss := []*srvtopo.ResolvedShard{rs} bqs := []*querypb.BoundQuery{ { @@ -801,8 +840,11 @@ func (vc *VCursorImpl) ExecuteStandalone(ctx context.Context, primitive engine.P } // The autocommit flag is always set to false because we currently don't // execute DMLs through ExecuteStandalone. - qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, bqs, NewAutocommitSession(vc.SafeSession.Session), false /* autocommit */, vc.ignoreMaxMemoryRows, vc.observer) + qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, bqs, NewAutocommitSession(vc.SafeSession.Session), false /* autocommit */, vc.ignoreMaxMemoryRows, vc.observer, fetchLastInsertID) vc.logShardsQueried(primitive, len(rss)) + if qr.InsertIDUpdated() { + vc.SafeSession.LastInsertId = qr.InsertID + } return qr, vterrors.Aggregate(errs) } @@ -829,7 +871,7 @@ func (vc *VCursorImpl) ExecuteKeyspaceID(ctx context.Context, keyspace string, k vc.SafeSession.SetQueryFromVindex(false) }() } - qr, errs := vc.ExecuteMultiShard(ctx, nil, rss, queries, rollbackOnError, autocommit) + qr, errs := vc.ExecuteMultiShard(ctx, nil, rss, queries, rollbackOnError, autocommit, false) return qr, vterrors.Aggregate(errs) } @@ -1294,7 +1336,7 @@ func (vc *VCursorImpl) GetAggregateUDFs() []string { // FindMirrorRule finds the mirror rule for the requested table name and // VSchema tablet type. func (vc *VCursorImpl) FindMirrorRule(name sqlparser.TableName) (*vindexes.MirrorRule, error) { - destKeyspace, destTabletType, _, err := vc.ParseDestinationTarget(name.Qualifier.String()) + destKeyspace, destTabletType, _, err := vc.parseDestinationTarget(name.Qualifier.String()) if err != nil { return nil, err } @@ -1359,7 +1401,10 @@ func (vc *VCursorImpl) ExecuteVSchema(ctx context.Context, keyspace string, vsch } // Resolve the keyspace either from the table qualifier or the target keyspace - var ksName string + var ( + ksName string + err error + ) if !vschemaDDL.Table.IsEmpty() { ksName = vschemaDDL.Table.Qualifier.String() } @@ -1370,15 +1415,14 @@ func (vc *VCursorImpl) ExecuteVSchema(ctx context.Context, keyspace string, vsch return ErrNoKeyspace } - ks := srvVschema.Keyspaces[ksName] - ks, err := topotools.ApplyVSchemaDDL(ksName, ks, vschemaDDL) + ksvs, err := topotools.ApplyVSchemaDDL(ctx, ksName, vc.topoServer, vschemaDDL) if err != nil { return err } - srvVschema.Keyspaces[ksName] = ks + srvVschema.Keyspaces[ksName] = ksvs.Keyspace - return vc.vm.UpdateVSchema(ctx, ksName, srvVschema) + return vc.vm.UpdateVSchema(ctx, ksvs, srvVschema) } func (vc *VCursorImpl) MessageStream(ctx context.Context, rss []*srvtopo.ResolvedShard, tableName string, callback func(*sqltypes.Result) error) error { @@ -1569,3 +1613,9 @@ func (vc *VCursorImpl) GetContextWithTimeOut(ctx context.Context) (context.Conte func (vc *VCursorImpl) IgnoreMaxMemoryRows() bool { return vc.ignoreMaxMemoryRows } + +func (vc *VCursorImpl) SetLastInsertID(id uint64) { + vc.SafeSession.mu.Lock() + defer vc.SafeSession.mu.Unlock() + vc.SafeSession.LastInsertId = id +} diff --git a/go/vt/vtgate/executorcontext/vcursor_impl_test.go b/go/vt/vtgate/executorcontext/vcursor_impl_test.go index 16d2c03bf1c..54173bf63b0 100644 --- a/go/vt/vtgate/executorcontext/vcursor_impl_test.go +++ b/go/vt/vtgate/executorcontext/vcursor_impl_test.go @@ -27,9 +27,13 @@ import ( "github.com/stretchr/testify/require" + "vitess.io/vitess/go/streamlog" + "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqltypes" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + "vitess.io/vitess/go/vt/proto/vschema" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/vtgateservice" @@ -56,7 +60,7 @@ func (f fakeVSchemaOperator) GetCurrentSrvVschema() *vschemapb.SrvVSchema { panic("implement me") } -func (f fakeVSchemaOperator) UpdateVSchema(ctx context.Context, ksName string, vschema *vschemapb.SrvVSchema) error { +func (f fakeVSchemaOperator) UpdateVSchema(ctx context.Context, ksvs *topo.KeyspaceVSchemaInfo, srvvs *vschema.SrvVSchema) error { panic("implement me") } @@ -367,7 +371,7 @@ func TestSetExecQueryTimeout(t *testing.T) { func TestRecordMirrorStats(t *testing.T) { safeSession := NewSafeSession(nil) - logStats := logstats.NewLogStats(context.Background(), t.Name(), "select 1", "", nil) + logStats := logstats.NewLogStats(context.Background(), t.Name(), "select 1", "", nil, streamlog.NewQueryLogConfigForTest()) vc, err := NewVCursorImpl(safeSession, sqlparser.MarginComments{}, nil, logStats, nil, &vindexes.VSchema{}, nil, nil, fakeObserver{}, VCursorConfig{}) require.NoError(t, err) @@ -389,12 +393,12 @@ func (f fakeExecutor) Execute(ctx context.Context, mysqlCtx vtgateservice.MySQLC panic("implement me") } -func (f fakeExecutor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver) (qr *sqltypes.Result, errs []error) { +func (f fakeExecutor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver, fetchLastInsertID bool) (qr *sqltypes.Result, errs []error) { // TODO implement me panic("implement me") } -func (f fakeExecutor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver) []error { +func (f fakeExecutor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver, fetchLastInsertID bool) []error { // TODO implement me panic("implement me") } diff --git a/go/vt/vtgate/grpcvtgateconn/suite_test.go b/go/vt/vtgate/grpcvtgateconn/suite_test.go index 0e544b05e66..32df3a2ab34 100644 --- a/go/vt/vtgate/grpcvtgateconn/suite_test.go +++ b/go/vt/vtgate/grpcvtgateconn/suite_test.go @@ -426,6 +426,7 @@ func testStreamExecute(t *testing.T, session *vtgateconn.VTGateSession) { wantResult := *execCase.result wantResult.RowsAffected = 0 wantResult.InsertID = 0 + wantResult.InsertIDChanged = false if !qr.Equal(&wantResult) { t.Errorf("Unexpected result from StreamExecute: got %+v want %+v", qr, wantResult) } @@ -563,8 +564,9 @@ var result1 = sqltypes.Result{ Type: sqltypes.Int32, }, }, - RowsAffected: 123, - InsertID: 72, + RowsAffected: 123, + InsertID: 72, + InsertIDChanged: true, Rows: [][]sqltypes.Value{ { sqltypes.TestValue(sqltypes.Int16, "1"), diff --git a/go/vt/vtgate/legacy_scatter_conn_test.go b/go/vt/vtgate/legacy_scatter_conn_test.go index 0d49e7b7bd9..fecd6c2a8b1 100644 --- a/go/vt/vtgate/legacy_scatter_conn_test.go +++ b/go/vt/vtgate/legacy_scatter_conn_test.go @@ -101,7 +101,7 @@ func TestLegacyExecuteFailOnAutocommit(t *testing.T) { }, Autocommit: false, } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}, false) err := vterrors.Aggregate(errs) require.Error(t, err) require.Contains(t, err.Error(), "in autocommit mode, transactionID should be zero but was: 123") @@ -125,7 +125,7 @@ func TestScatterConnExecuteMulti(t *testing.T) { } } - qr, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(nil), false /*autocommit*/, false, nullResultsObserver{}) + qr, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(nil), false /*autocommit*/, false, nullResultsObserver{}, false) return qr, vterrors.Aggregate(errs) }) } @@ -145,7 +145,7 @@ func TestScatterConnStreamExecuteMulti(t *testing.T) { defer mu.Unlock() qr.AppendResult(r) return nil - }, nullResultsObserver{}) + }, nullResultsObserver{}, false) return qr, vterrors.Aggregate(errors) }) } @@ -312,7 +312,7 @@ func TestMaxMemoryRows(t *testing.T) { sbc0.SetResults([]*sqltypes.Result{tworows, tworows}) sbc1.SetResults([]*sqltypes.Result{tworows, tworows}) - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, test.ignoreMaxMemoryRows, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, test.ignoreMaxMemoryRows, nullResultsObserver{}, false) if test.ignoreMaxMemoryRows { require.NoError(t, err) } else { @@ -344,7 +344,7 @@ func TestLegaceHealthCheckFailsOnReservedConnections(t *testing.T) { }) } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}, false) require.Error(t, vterrors.Aggregate(errs)) } @@ -367,7 +367,7 @@ func executeOnShardsReturnsErr(t *testing.T, ctx context.Context, res *srvtopo.R }) } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}, false) return vterrors.Aggregate(errs) } @@ -432,7 +432,7 @@ func TestMultiExecs(t *testing.T) { observer := recordingResultsObserver{} session := econtext.NewSafeSession(&vtgatepb.Session{}) - _, err := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, &observer) + _, err := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, &observer, false) require.NoError(t, vterrors.Aggregate(err)) if len(sbc0.Queries) == 0 || len(sbc1.Queries) == 0 { t.Fatalf("didn't get expected query") @@ -484,7 +484,7 @@ func TestMultiExecs(t *testing.T) { observer = recordingResultsObserver{} _ = sc.StreamExecuteMulti(ctx, nil, "query", rss, bvs, session, false /* autocommit */, func(*sqltypes.Result) error { return nil - }, &observer) + }, &observer, false) if !reflect.DeepEqual(sbc0.Queries[0].BindVariables, wantVars0) { t.Errorf("got %+v, want %+v", sbc0.Queries[0].BindVariables, wantVars0) } @@ -515,27 +515,27 @@ func TestScatterConnSingleDB(t *testing.T) { // TransactionMode_SINGLE in session session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, TransactionMode: vtgatepb.TransactionMode_SINGLE}) queries := []*querypb.BoundQuery{{Sql: "query1"}} - _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Error(t, errors[0]) assert.Contains(t, errors[0].Error(), want) // TransactionMode_SINGLE in txconn - sc.txConn.mode = vtgatepb.TransactionMode_SINGLE + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_SINGLE} session = econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Error(t, errors[0]) assert.Contains(t, errors[0].Error(), want) // TransactionMode_MULTI in txconn. Should not fail. - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} session = econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) } @@ -622,6 +622,8 @@ func newTestScatterConn(ctx context.Context, hc discovery.HealthCheck, serv srvt // in '-cells_to_watch' command line parameter, which is // empty by default. So it's unused in this test, set to nil. gw := NewTabletGateway(ctx, hc, serv, cell) - tc := NewTxConn(gw, vtgatepb.TransactionMode_MULTI) + tc := NewTxConn(gw, &StaticConfig{ + TxMode: vtgatepb.TransactionMode_MULTI, + }) return NewScatterConn("", tc, gw) } diff --git a/go/vt/vtgate/logstats/logstats.go b/go/vt/vtgate/logstats/logstats.go index fdc0e69c8db..3ad75d07722 100644 --- a/go/vt/vtgate/logstats/logstats.go +++ b/go/vt/vtgate/logstats/logstats.go @@ -33,6 +33,8 @@ import ( // LogStats records the stats for a single vtgate query type LogStats struct { + Config streamlog.QueryLogConfig + Ctx context.Context Method string TabletType string @@ -59,7 +61,7 @@ type LogStats struct { // NewLogStats constructs a new LogStats with supplied Method and ctx // field values, and the StartTime field set to the present time. -func NewLogStats(ctx context.Context, methodName, sql, sessionUUID string, bindVars map[string]*querypb.BindVariable) *LogStats { +func NewLogStats(ctx context.Context, methodName, sql, sessionUUID string, bindVars map[string]*querypb.BindVariable, config streamlog.QueryLogConfig) *LogStats { return &LogStats{ Ctx: ctx, Method: methodName, @@ -67,6 +69,7 @@ func NewLogStats(ctx context.Context, methodName, sql, sessionUUID string, bindV SessionUUID: sessionUUID, BindVariables: bindVars, StartTime: time.Now(), + Config: config, } } @@ -130,16 +133,15 @@ func (stats *LogStats) MirrorTargetErrorStr() string { // Logf formats the log record to the given writer, either as // tab-separated list of logged fields or as JSON. func (stats *LogStats) Logf(w io.Writer, params url.Values) error { - if !streamlog.ShouldEmitLog(stats.SQL, stats.RowsAffected, stats.RowsReturned) { + if !stats.Config.ShouldEmitLog(stats.SQL, stats.RowsAffected, stats.RowsReturned, stats.Error != nil) { return nil } - redacted := streamlog.GetRedactDebugUIQueries() _, fullBindParams := params["full"] remoteAddr, username := stats.RemoteAddrUsername() log := logstats.NewLogger() - log.Init(streamlog.GetQueryLogFormat() == streamlog.QueryLogFormatJSON) + log.Init(stats.Config.Format == streamlog.QueryLogFormatJSON) log.Key("Method") log.StringUnquoted(stats.Method) log.Key("RemoteAddr") @@ -167,7 +169,7 @@ func (stats *LogStats) Logf(w io.Writer, params url.Values) error { log.Key("SQL") log.String(stats.SQL) log.Key("BindVars") - if redacted { + if stats.Config.RedactDebugUIQueries { log.Redacted() } else { log.BindVariables(stats.BindVariables, fullBindParams) diff --git a/go/vt/vtgate/logstats/logstats_test.go b/go/vt/vtgate/logstats/logstats_test.go index 872b34c6964..78b27342a7e 100644 --- a/go/vt/vtgate/logstats/logstats_test.go +++ b/go/vt/vtgate/logstats/logstats_test.go @@ -55,11 +55,7 @@ func testFormat(t *testing.T, stats *LogStats, params url.Values) string { } func TestLogStatsFormat(t *testing.T) { - defer func() { - streamlog.SetRedactDebugUIQueries(false) - streamlog.SetQueryLogFormat("text") - }() - logStats := NewLogStats(context.Background(), "test", "sql1", "suuid", nil) + logStats := NewLogStats(context.Background(), "test", "sql1", "suuid", nil, streamlog.NewQueryLogConfigForTest()) logStats.StartTime = time.Date(2017, time.January, 1, 1, 2, 3, 0, time.UTC) logStats.EndTime = time.Date(2017, time.January, 1, 1, 2, 4, 1234, time.UTC) logStats.TablesUsed = []string{"ks1.tbl1", "ks2.tbl2"} @@ -125,8 +121,8 @@ func TestLogStatsFormat(t *testing.T) { for _, variable := range logStats.BindVariables { fmt.Println("->" + fmt.Sprintf("%v", variable)) } - streamlog.SetRedactDebugUIQueries(test.redact) - streamlog.SetQueryLogFormat(test.format) + logStats.Config.RedactDebugUIQueries = test.redact + logStats.Config.Format = test.format if test.format == "text" { got := testFormat(t, logStats, params) t.Logf("got: %s", got) @@ -148,9 +144,8 @@ func TestLogStatsFormat(t *testing.T) { } func TestLogStatsFilter(t *testing.T) { - defer func() { streamlog.SetQueryLogFilterTag("") }() - - logStats := NewLogStats(context.Background(), "test", "sql1 /* LOG_THIS_QUERY */", "", map[string]*querypb.BindVariable{"intVal": sqltypes.Int64BindVariable(1)}) + logStats := NewLogStats(context.Background(), "test", "sql1 /* LOG_THIS_QUERY */", "", + map[string]*querypb.BindVariable{"intVal": sqltypes.Int64BindVariable(1)}, streamlog.NewQueryLogConfigForTest()) logStats.StartTime = time.Date(2017, time.January, 1, 1, 2, 3, 0, time.UTC) logStats.EndTime = time.Date(2017, time.January, 1, 1, 2, 4, 1234, time.UTC) params := map[string][]string{"full": {}} @@ -159,21 +154,20 @@ func TestLogStatsFilter(t *testing.T) { want := "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t0.000000\t0.000000\t0.000000\t\t\"sql1 /* LOG_THIS_QUERY */\"\t{\"intVal\": {\"type\": \"INT64\", \"value\": 1}}\t0\t0\t\"\"\t\"\"\t\"\"\tfalse\t[]\t\"\"\t0.000000\t0.000000\t\"\"\n" assert.Equal(t, want, got) - streamlog.SetQueryLogFilterTag("LOG_THIS_QUERY") + logStats.Config.FilterTag = "LOG_THIS_QUERY" got = testFormat(t, logStats, params) want = "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t0.000000\t0.000000\t0.000000\t\t\"sql1 /* LOG_THIS_QUERY */\"\t{\"intVal\": {\"type\": \"INT64\", \"value\": 1}}\t0\t0\t\"\"\t\"\"\t\"\"\tfalse\t[]\t\"\"\t0.000000\t0.000000\t\"\"\n" assert.Equal(t, want, got) - streamlog.SetQueryLogFilterTag("NOT_THIS_QUERY") + logStats.Config.FilterTag = "NOT_THIS_QUERY" got = testFormat(t, logStats, params) want = "" assert.Equal(t, want, got) } func TestLogStatsRowThreshold(t *testing.T) { - defer func() { streamlog.SetQueryLogRowThreshold(0) }() - - logStats := NewLogStats(context.Background(), "test", "sql1 /* LOG_THIS_QUERY */", "", map[string]*querypb.BindVariable{"intVal": sqltypes.Int64BindVariable(1)}) + logStats := NewLogStats(context.Background(), "test", "sql1 /* LOG_THIS_QUERY */", "", + map[string]*querypb.BindVariable{"intVal": sqltypes.Int64BindVariable(1)}, streamlog.NewQueryLogConfigForTest()) logStats.StartTime = time.Date(2017, time.January, 1, 1, 2, 3, 0, time.UTC) logStats.EndTime = time.Date(2017, time.January, 1, 1, 2, 4, 1234, time.UTC) params := map[string][]string{"full": {}} @@ -182,11 +176,11 @@ func TestLogStatsRowThreshold(t *testing.T) { want := "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t0.000000\t0.000000\t0.000000\t\t\"sql1 /* LOG_THIS_QUERY */\"\t{\"intVal\": {\"type\": \"INT64\", \"value\": 1}}\t0\t0\t\"\"\t\"\"\t\"\"\tfalse\t[]\t\"\"\t0.000000\t0.000000\t\"\"\n" assert.Equal(t, want, got) - streamlog.SetQueryLogRowThreshold(0) got = testFormat(t, logStats, params) want = "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t0.000000\t0.000000\t0.000000\t\t\"sql1 /* LOG_THIS_QUERY */\"\t{\"intVal\": {\"type\": \"INT64\", \"value\": 1}}\t0\t0\t\"\"\t\"\"\t\"\"\tfalse\t[]\t\"\"\t0.000000\t0.000000\t\"\"\n" assert.Equal(t, want, got) - streamlog.SetQueryLogRowThreshold(1) + + logStats.Config.RowThreshold = 1 got = testFormat(t, logStats, params) assert.Empty(t, got) } @@ -197,14 +191,14 @@ func TestLogStatsContextHTML(t *testing.T) { Html: testconversions.MakeHTMLForTest(html), } ctx := callinfo.NewContext(context.Background(), callInfo) - logStats := NewLogStats(ctx, "test", "sql1", "", map[string]*querypb.BindVariable{}) + logStats := NewLogStats(ctx, "test", "sql1", "", map[string]*querypb.BindVariable{}, streamlog.NewQueryLogConfigForTest()) if logStats.ContextHTML().String() != html { t.Fatalf("expect to get html: %s, but got: %s", html, logStats.ContextHTML().String()) } } func TestLogStatsErrorStr(t *testing.T) { - logStats := NewLogStats(context.Background(), "test", "sql1", "", map[string]*querypb.BindVariable{}) + logStats := NewLogStats(context.Background(), "test", "sql1", "", map[string]*querypb.BindVariable{}, streamlog.NewQueryLogConfigForTest()) if logStats.ErrorStr() != "" { t.Fatalf("should not get error in stats, but got: %s", logStats.ErrorStr()) } @@ -216,7 +210,7 @@ func TestLogStatsErrorStr(t *testing.T) { } func TestLogStatsMirrorTargetErrorStr(t *testing.T) { - logStats := NewLogStats(context.Background(), "test", "sql1", "", map[string]*querypb.BindVariable{}) + logStats := NewLogStats(context.Background(), "test", "sql1", "", map[string]*querypb.BindVariable{}, streamlog.NewQueryLogConfigForTest()) if logStats.MirrorTargetErrorStr() != "" { t.Fatalf("should not get error in stats, but got: %s", logStats.ErrorStr()) } @@ -228,7 +222,7 @@ func TestLogStatsMirrorTargetErrorStr(t *testing.T) { } func TestLogStatsRemoteAddrUsername(t *testing.T) { - logStats := NewLogStats(context.Background(), "test", "sql1", "", map[string]*querypb.BindVariable{}) + logStats := NewLogStats(context.Background(), "test", "sql1", "", map[string]*querypb.BindVariable{}, streamlog.NewQueryLogConfigForTest()) addr, user := logStats.RemoteAddrUsername() if addr != "" { t.Fatalf("remote addr should be empty") @@ -244,7 +238,7 @@ func TestLogStatsRemoteAddrUsername(t *testing.T) { User: username, } ctx := callinfo.NewContext(context.Background(), callInfo) - logStats = NewLogStats(ctx, "test", "sql1", "", map[string]*querypb.BindVariable{}) + logStats = NewLogStats(ctx, "test", "sql1", "", map[string]*querypb.BindVariable{}, streamlog.NewQueryLogConfigForTest()) addr, user = logStats.RemoteAddrUsername() if addr != remoteAddr { t.Fatalf("expected to get remote addr: %s, but got: %s", remoteAddr, addr) @@ -253,3 +247,18 @@ func TestLogStatsRemoteAddrUsername(t *testing.T) { t.Fatalf("expected to get username: %s, but got: %s", username, user) } } + +// TestLogStatsErrorsOnly tests that LogStats only logs errors when the query log mode is set to errors only for VTGate. +func TestLogStatsErrorsOnly(t *testing.T) { + logStats := NewLogStats(context.Background(), "test", "sql1", "", map[string]*querypb.BindVariable{}, streamlog.NewQueryLogConfigForTest()) + logStats.Config.Mode = streamlog.QueryLogModeError + + // no error, should not log + logOutput := testFormat(t, logStats, url.Values{}) + assert.Empty(t, logOutput) + + // error, should log + logStats.Error = errors.New("test error") + logOutput = testFormat(t, logStats, url.Values{}) + assert.Contains(t, logOutput, "test error") +} diff --git a/go/vt/vtgate/plan_execute.go b/go/vt/vtgate/plan_execute.go index db7923c09f0..75a7af6bf2a 100644 --- a/go/vt/vtgate/plan_execute.go +++ b/go/vt/vtgate/plan_execute.go @@ -131,7 +131,7 @@ func (e *Executor) newExecute( // the vtgate to clear the cached plans when processing the new serving vschema. // When buffering ends, many queries might be getting planned at the same time and we then // take full advatange of the cached plan. - plan, err = e.getPlan(ctx, vcursor, query, stmt, comments, bindVars, reservedVars, e.normalize, logStats) + plan, err = e.getPlan(ctx, vcursor, query, stmt, comments, bindVars, reservedVars, e.config.Normalize, logStats) execStart := e.logPlanningFinished(logStats, plan) if err != nil { diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index ca4ccb7ac5a..065c50a6dfa 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -43,10 +43,6 @@ const ( Gen4Left2Right = querypb.ExecuteOptions_Gen4Left2Right ) -var ( - plannerVersions = []plancontext.PlannerVersion{Gen4, Gen4GreedyOnly, Gen4Left2Right} -) - type ( planResult struct { primitive engine.Primitive diff --git a/go/vt/vtgate/planbuilder/bypass.go b/go/vt/vtgate/planbuilder/bypass.go index d3384d509c1..6e3f64990d7 100644 --- a/go/vt/vtgate/planbuilder/bypass.go +++ b/go/vt/vtgate/planbuilder/bypass.go @@ -56,6 +56,8 @@ func buildPlanForBypass(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, vsc } } + sqlparser.RemoveSpecificKeyspace(stmt, keyspace.Name) + send := &engine.Send{ Keyspace: keyspace, TargetDestination: vschema.Destination(), diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index a0045cec060..2ca924c31ab 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -196,9 +196,13 @@ func buildCreateViewCommon( vschema plancontext.VSchema, reservedVars *sqlparser.ReservedVars, cfg dynamicconfig.DDL, - ddlSelect sqlparser.SelectStatement, + ddlSelect sqlparser.TableStatement, ddl sqlparser.DDLStatement, ) (key.Destination, *vindexes.Keyspace, error) { + if vschema.IsViewsEnabled() { + return createViewEnabled(vschema, reservedVars, ddlSelect, ddl) + } + // For Create View, we require that the keyspace exist and the select query can be satisfied within the keyspace itself // We should remove the keyspace name from the table name, as the database name in MySQL might be different than the keyspace name destination, keyspace, err := findTableDestinationAndKeyspace(vschema, ddl) @@ -228,9 +232,6 @@ func buildCreateViewCommon( sqlparser.RemoveKeyspace(ddl) - if vschema.IsViewsEnabled() { - return destination, keyspace, nil - } isRoutePlan, opCode := tryToGetRoutePlan(selectPlan.primitive) if !isRoutePlan { return nil, nil, vterrors.VT12001(ViewComplex) @@ -241,6 +242,55 @@ func buildCreateViewCommon( return destination, keyspace, nil } +func createViewEnabled(vschema plancontext.VSchema, reservedVars *sqlparser.ReservedVars, ddlSelect sqlparser.TableStatement, ddl sqlparser.DDLStatement) (key.Destination, *vindexes.Keyspace, error) { + // For Create View, we require that the keyspace exist and the select query can be satisfied within the keyspace itself + // We should remove the keyspace name from the table name, as the database name in MySQL might be different than the keyspace name + destination, keyspace, err := findTableDestinationAndKeyspace(vschema, ddl) + if err != nil { + return nil, nil, err + } + + // views definition with `select *` should not be expanded as schema tracker might not be up-to-date + // We copy the expressions and restore them after the planning context is created + var expressions []sqlparser.SelectExprs + _ = sqlparser.VisitAllSelects(ddlSelect, func(p *sqlparser.Select, idx int) error { + expressions = append(expressions, sqlparser.Clone(p.SelectExprs)) + return nil + }) + + pCtx, err := plancontext.CreatePlanningContext(ddlSelect, reservedVars, vschema, Gen4) + if err != nil { + return nil, nil, err + } + + var tblKs string + for _, tbl := range pCtx.SemTable.Tables { + vTbl := tbl.GetVindexTable() + if vTbl == nil { + continue + } + if tblKs == "" { + tblKs = vTbl.Keyspace.Name + } + if tblKs != vTbl.Keyspace.Name { + return nil, nil, vterrors.VT12001(ViewComplex) + } + } + + if tblKs != keyspace.Name { + return nil, nil, vterrors.VT12001(ViewDifferentKeyspace) + } + + _ = sqlparser.VisitAllSelects(ddlSelect, func(p *sqlparser.Select, idx int) error { + p.SelectExprs = expressions[idx] + return nil + }) + + sqlparser.RemoveKeyspace(ddl) + + return destination, keyspace, nil +} + func buildDropView(vschema plancontext.VSchema, ddlStatement sqlparser.DDLStatement) (key.Destination, *vindexes.Keyspace, error) { if !vschema.IsViewsEnabled() { return buildDropTable(vschema, ddlStatement) @@ -248,7 +298,7 @@ func buildDropView(vschema plancontext.VSchema, ddlStatement sqlparser.DDLStatem var ks *vindexes.Keyspace viewMap := make(map[string]any) for _, tbl := range ddlStatement.GetFromTables() { - _, ksForView, _, err := vschema.TargetDestination(tbl.Qualifier.String()) + ksForView, err := vschema.FindViewTarget(tbl) if err != nil { return nil, nil, err } diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 80516871623..d3ad5afac72 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -51,7 +51,7 @@ func gen4InsertStmtPlanner(version querypb.ExecuteOptions_PlannerVersion, insStm } if ks != nil { if tables[0].AutoIncrement == nil && !ctx.SemTable.ForeignKeysPresent() { - plan := insertUnshardedShortcut(insStmt, ks, tables) + plan := insertUnshardedShortcut(ctx, insStmt, ks, tables) setCommentDirectivesOnPlan(plan, insStmt) return newPlanResult(plan, operators.QualifiedTables(ks, tables)...), nil } @@ -90,12 +90,13 @@ func errOutIfPlanCannotBeConstructed(ctx *plancontext.PlanningContext, vTbl *vin return ctx.SemTable.NotUnshardedErr } -func insertUnshardedShortcut(stmt *sqlparser.Insert, ks *vindexes.Keyspace, tables []*vindexes.Table) engine.Primitive { +func insertUnshardedShortcut(ctx *plancontext.PlanningContext, stmt *sqlparser.Insert, ks *vindexes.Keyspace, tables []*vindexes.Table) engine.Primitive { eIns := &engine.Insert{ InsertCommon: engine.InsertCommon{ - Opcode: engine.InsertUnsharded, - Keyspace: ks, - TableName: tables[0].Name.String(), + Opcode: engine.InsertUnsharded, + Keyspace: ks, + TableName: tables[0].Name.String(), + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), }, } eIns.Query = generateQuery(stmt) diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index df14745e6b2..b51eac449fc 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -22,12 +22,10 @@ import ( "strconv" "strings" - "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/slice" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/sysvars" - "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/engine/opcode" @@ -192,6 +190,7 @@ func transformInsertionSelection(ctx *plancontext.PlanningContext, op *operators ForceNonStreaming: op.ForceNonStreaming, Generate: autoIncGenerate(ins.AutoIncrement), ColVindexes: ins.ColVindexes, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), }, VindexValueOffset: ins.VindexValueOffset, } @@ -536,6 +535,7 @@ func routeToEngineRoute(ctx *plancontext.PlanningContext, op *operators.Route, h TableName: strings.Join(tableNames, ", "), RoutingParameters: rp, TruncateColumnCount: op.ResultColumns, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), } if hints != nil { e.ScatterErrorsAsWarnings = hints.scatterErrorsAsWarnings @@ -601,7 +601,7 @@ func transformRoutePlan(ctx *plancontext.PlanningContext, op *operators.Route) ( case *sqlparser.Delete: return buildDeletePrimitive(ctx, op, dmlOp, stmt, hints) case *sqlparser.Insert: - return buildInsertPrimitive(op, dmlOp, stmt, hints) + return buildInsertPrimitive(ctx, op, dmlOp, stmt, hints) default: return nil, vterrors.VT13001(fmt.Sprintf("dont know how to %T", stmt)) } @@ -637,18 +637,22 @@ func buildRoutePrimitive(ctx *plancontext.PlanningContext, op *operators.Route, } func buildInsertPrimitive( - rb *operators.Route, op operators.Operator, stmt *sqlparser.Insert, + ctx *plancontext.PlanningContext, + rb *operators.Route, + op operators.Operator, + stmt *sqlparser.Insert, hints *queryHints, ) (engine.Primitive, error) { ins := op.(*operators.Insert) ic := engine.InsertCommon{ - Opcode: mapToInsertOpCode(rb.Routing.OpCode()), - Keyspace: rb.Routing.Keyspace(), - TableName: ins.VTable.Name.String(), - Ignore: ins.Ignore, - Generate: autoIncGenerate(ins.AutoIncrement), - ColVindexes: ins.ColVindexes, + Opcode: mapToInsertOpCode(rb.Routing.OpCode()), + Keyspace: rb.Routing.Keyspace(), + TableName: ins.VTable.Name.String(), + Ignore: ins.Ignore, + Generate: autoIncGenerate(ins.AutoIncrement), + ColVindexes: ins.ColVindexes, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), } if hints != nil { ic.MultiShardAutocommit = hints.multiShardAutocommit @@ -788,6 +792,7 @@ func createDMLPrimitive(ctx *plancontext.PlanningContext, rb *operators.Route, h Vindexes: colVindexes, OwnedVindexQuery: vindexQuery, RoutingParameters: rp, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), } if rb.Routing.OpCode() != engine.Unsharded && vindexQuery != "" { @@ -880,18 +885,18 @@ func transformUnionPlan(ctx *plancontext.PlanningContext, op *operators.Union) ( } func transformLimit(ctx *plancontext.PlanningContext, op *operators.Limit) (engine.Primitive, error) { - plan, err := transformToPrimitive(ctx, op.Source) + input, err := transformToPrimitive(ctx, op.Source) if err != nil { return nil, err } - return createLimit(plan, op.AST, ctx.VSchema.Environment(), ctx.VSchema.ConnCollation()) + return createLimit(ctx, input, op.AST) } -func createLimit(input engine.Primitive, limit *sqlparser.Limit, env *vtenv.Environment, coll collations.ID) (engine.Primitive, error) { +func createLimit(ctx *plancontext.PlanningContext, input engine.Primitive, limit *sqlparser.Limit) (engine.Primitive, error) { cfg := &evalengine.Config{ - Collation: coll, - Environment: env, + Collation: ctx.VSchema.ConnCollation(), + Environment: ctx.VSchema.Environment(), } count, err := evalengine.Translate(limit.Rowcount, cfg) if err != nil { @@ -906,9 +911,10 @@ func createLimit(input engine.Primitive, limit *sqlparser.Limit, env *vtenv.Envi } return &engine.Limit{ - Input: input, - Count: count, - Offset: offset, + Count: count, + Offset: offset, + RequireCompleteInput: ctx.SemTable.ShouldFetchLastInsertID(), + Input: input, }, nil } diff --git a/go/vt/vtgate/planbuilder/operators/SQL_builder.go b/go/vt/vtgate/planbuilder/operators/SQL_builder.go index fc91569981d..ca15b5c9134 100644 --- a/go/vt/vtgate/planbuilder/operators/SQL_builder.go +++ b/go/vt/vtgate/planbuilder/operators/SQL_builder.go @@ -37,8 +37,9 @@ type ( } ) -func (qb *queryBuilder) asSelectStatement() sqlparser.SelectStatement { - return qb.stmt.(sqlparser.SelectStatement) +func (qb *queryBuilder) asSelectStatement() sqlparser.TableStatement { + return qb.stmt.(sqlparser.TableStatement) + } func (qb *queryBuilder) asOrderAndLimit() sqlparser.OrderAndLimit { return qb.stmt.(sqlparser.OrderAndLimit) @@ -191,7 +192,8 @@ func (qb *queryBuilder) pushUnionInsideDerived() { As: sqlparser.NewIdentifierCS("dt"), }}, } - sel.SelectExprs = unionSelects(sqlparser.GetFirstSelect(selStmt).SelectExprs) + firstSelect := getFirstSelect(selStmt) + sel.SelectExprs = unionSelects(firstSelect.SelectExprs) qb.stmt = sel } @@ -208,9 +210,10 @@ func unionSelects(exprs sqlparser.SelectExprs) (selectExprs sqlparser.SelectExpr return } -func checkUnionColumnByName(column *sqlparser.ColName, sel sqlparser.SelectStatement) { +func checkUnionColumnByName(column *sqlparser.ColName, sel sqlparser.TableStatement) { colName := column.Name.String() - exprs := sqlparser.GetFirstSelect(sel).SelectExprs + firstSelect := getFirstSelect(sel) + exprs := firstSelect.SelectExprs offset := slices.IndexFunc(exprs, func(expr sqlparser.SelectExpr) bool { switch ae := expr.(type) { case *sqlparser.StarExpr: @@ -244,8 +247,8 @@ func (qb *queryBuilder) unionWith(other *queryBuilder, distinct bool) { func (qb *queryBuilder) recursiveCteWith(other *queryBuilder, name, alias string, distinct bool, columns sqlparser.Columns) { cteUnion := &sqlparser.Union{ - Left: qb.stmt.(sqlparser.SelectStatement), - Right: other.stmt.(sqlparser.SelectStatement), + Left: qb.stmt.(sqlparser.TableStatement), + Right: other.stmt.(sqlparser.TableStatement), Distinct: distinct, } @@ -393,7 +396,7 @@ func removeKeyspaceFromSelectExpr(expr sqlparser.SelectExpr) { } } -func stripDownQuery(from, to sqlparser.SelectStatement) { +func stripDownQuery(from, to sqlparser.TableStatement) { switch node := from.(type) { case *sqlparser.Select: toNode, ok := to.(*sqlparser.Select) @@ -450,7 +453,12 @@ func buildQuery(op Operator, qb *queryBuilder) { buildUnion(op, qb) case *Distinct: buildQuery(op.Source, qb) - qb.asSelectStatement().MakeDistinct() + statement := qb.asSelectStatement() + d, ok := statement.(sqlparser.Distinctable) + if !ok { + panic(vterrors.VT13001("expected a select statement with distinct")) + } + d.MakeDistinct() case *Update: buildUpdate(op, qb) case *Delete: diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index 73169369a41..ced81df147a 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -544,7 +544,7 @@ func splitAggrColumnsToLeftAndRight( canPushDistinctAggr, distinctExprs := checkIfWeCanPush(ctx, aggregator) - // Distinct aggregation cannot be pushed down in the join. + // Distinctable aggregation cannot be pushed down in the join. // We keep node of the distinct aggregation expression to be used later for ordering. if !canPushDistinctAggr { if len(distinctExprs) != 1 { diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index 12c19bb72a6..2e3781c94db 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -178,7 +178,7 @@ func createOperatorFromUnion(ctx *plancontext.PlanningContext, node *sqlparser.U return newHorizon(union, node) } -func translateQueryToOpForUnion(ctx *plancontext.PlanningContext, node sqlparser.SelectStatement) Operator { +func translateQueryToOpForUnion(ctx *plancontext.PlanningContext, node sqlparser.TableStatement) Operator { op := translateQueryToOp(ctx, node) if hz, ok := op.(*Horizon); ok { hz.Truncate = true diff --git a/go/vt/vtgate/planbuilder/operators/cte_merging.go b/go/vt/vtgate/planbuilder/operators/cte_merging.go index cb19e06b2a7..0c1556c81e4 100644 --- a/go/vt/vtgate/planbuilder/operators/cte_merging.go +++ b/go/vt/vtgate/planbuilder/operators/cte_merging.go @@ -31,7 +31,7 @@ func tryMergeRecurse(ctx *plancontext.PlanningContext, in *RecurseCTE) (Operator } func tryMergeCTE(ctx *plancontext.PlanningContext, seed, term Operator, in *RecurseCTE) *Route { - seedRoute, termRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(seed, term) + seedRoute, termRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(ctx, seed, term) if seedRoute == nil { return nil } diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index 81e36d54315..015220470e0 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -124,7 +124,7 @@ func createDeleteWithInputOp(ctx *plancontext.PlanningContext, del *sqlparser.De } var delOps []dmlOp - for _, target := range ctx.SemTable.Targets.Constituents() { + for _, target := range ctx.SemTable.DMLTargets.Constituents() { op := createDeleteOpWithTarget(ctx, target, del.Ignore) delOps = append(delOps, op) } @@ -322,7 +322,7 @@ func updateQueryGraphWithSource(ctx *plancontext.PlanningContext, input Operator return op, NoRewrite } if len(qg.Tables) > 1 { - panic(vterrors.VT12001("DELETE on reference table with join")) + panic(vterrors.VT12001("DML on reference table with join")) } for _, tbl := range qg.Tables { if tbl.ID != tblID { diff --git a/go/vt/vtgate/planbuilder/operators/expressions.go b/go/vt/vtgate/planbuilder/operators/expressions.go index 38848693775..f42ec87404d 100644 --- a/go/vt/vtgate/planbuilder/operators/expressions.go +++ b/go/vt/vtgate/planbuilder/operators/expressions.go @@ -121,3 +121,11 @@ func simplifyPredicates(ctx *plancontext.PlanningContext, in sqlparser.Expr) sql } return output } + +func getFirstSelect(selStmt sqlparser.TableStatement) *sqlparser.Select { + firstSelect, err := sqlparser.GetFirstSelect(selStmt) + if err != nil { + panic(err) + } + return firstSelect +} diff --git a/go/vt/vtgate/planbuilder/operators/horizon.go b/go/vt/vtgate/planbuilder/operators/horizon.go index 292be1b37c5..aa7737001d6 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon.go +++ b/go/vt/vtgate/planbuilder/operators/horizon.go @@ -45,7 +45,7 @@ type Horizon struct { // QP contains the QueryProjection for this op QP *QueryProjection - Query sqlparser.SelectStatement + Query sqlparser.TableStatement // Columns needed to feed other plans Columns []*sqlparser.ColName @@ -54,7 +54,7 @@ type Horizon struct { Truncate bool } -func newHorizon(src Operator, query sqlparser.SelectStatement) *Horizon { +func newHorizon(src Operator, query sqlparser.TableStatement) *Horizon { return &Horizon{ unaryOperator: newUnaryOp(src), Query: query, @@ -148,7 +148,7 @@ func (h *Horizon) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, return -1 } - for idx, se := range sqlparser.GetFirstSelect(h.Query).SelectExprs { + for idx, se := range getFirstSelect(h.Query).SelectExprs { ae, ok := se.(*sqlparser.AliasedExpr) if !ok { panic(vterrors.VT09015()) @@ -174,7 +174,7 @@ func (h *Horizon) GetColumns(ctx *plancontext.PlanningContext) (exprs []*sqlpars } func (h *Horizon) GetSelectExprs(*plancontext.PlanningContext) sqlparser.SelectExprs { - return sqlparser.GetFirstSelect(h.Query).SelectExprs + return getFirstSelect(h.Query).SelectExprs } func (h *Horizon) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { @@ -185,7 +185,7 @@ func (h *Horizon) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { } // TODO: REMOVE -func (h *Horizon) selectStatement() sqlparser.SelectStatement { +func (h *Horizon) selectStatement() sqlparser.TableStatement { return h.Query } diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index 4ce37901a77..ae125dea19c 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -394,7 +394,7 @@ func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.I case sqlparser.Values: op = route route.Source = insertRowsPlan(ctx, insOp, insStmt, rows) - case sqlparser.SelectStatement: + case sqlparser.TableStatement: op = insertSelectPlan(ctx, insOp, route, insStmt, rows) } if insStmt.Comments != nil { @@ -408,7 +408,7 @@ func insertSelectPlan( insOp *Insert, routeOp *Route, ins *sqlparser.Insert, - sel sqlparser.SelectStatement, + sel sqlparser.TableStatement, ) *InsertSelection { if columnMismatch(insOp.AutoIncrement, ins, sel) { panic(vterrors.VT03006()) @@ -457,7 +457,7 @@ func insertSelectPlan( return insertSelect } -func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.SelectStatement) bool { +func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.TableStatement) bool { origColCount := len(ins.Columns) if gen != nil && gen.added { // One column got added to the insert query ast for auto increment column. @@ -468,7 +468,7 @@ func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.SelectSt return true } if origColCount > sel.GetColumnCount() { - sel := sqlparser.GetFirstSelect(sel) + sel := getFirstSelect(sel) var hasStarExpr bool for _, sExpr := range sel.SelectExprs { if _, hasStarExpr = sExpr.(*sqlparser.StarExpr); hasStarExpr { diff --git a/go/vt/vtgate/planbuilder/operators/join_merging.go b/go/vt/vtgate/planbuilder/operators/join_merging.go index c035b7d11ed..cb3569cf79e 100644 --- a/go/vt/vtgate/planbuilder/operators/join_merging.go +++ b/go/vt/vtgate/planbuilder/operators/join_merging.go @@ -28,7 +28,7 @@ import ( // If they can be merged, a new operator with the merged routing is returned // If they cannot be merged, nil is returned. func (jm *joinMerger) mergeJoinInputs(ctx *plancontext.PlanningContext, lhs, rhs Operator, joinPredicates []sqlparser.Expr) *Route { - lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(lhs, rhs) + lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(ctx, lhs, rhs) if lhsRoute == nil { return nil } @@ -102,13 +102,13 @@ func mergeAnyShardRoutings(ctx *plancontext.PlanningContext, a, b *AnyShardRouti } } -func prepareInputRoutes(lhs Operator, rhs Operator) (*Route, *Route, Routing, Routing, routingType, routingType, bool) { +func prepareInputRoutes(ctx *plancontext.PlanningContext, lhs Operator, rhs Operator) (*Route, *Route, Routing, Routing, routingType, routingType, bool) { lhsRoute, rhsRoute := operatorsToRoutes(lhs, rhs) if lhsRoute == nil || rhsRoute == nil { return nil, nil, nil, nil, 0, 0, false } - lhsRoute, rhsRoute, routingA, routingB, sameKeyspace := getRoutesOrAlternates(lhsRoute, rhsRoute) + lhsRoute, rhsRoute, routingA, routingB, sameKeyspace := getRoutesOrAlternates(ctx, lhsRoute, rhsRoute) a, b := getRoutingType(routingA), getRoutingType(routingB) return lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace @@ -159,7 +159,7 @@ func (rt routingType) String() string { // getRoutesOrAlternates gets the Routings from each Route. If they are from different keyspaces, // we check if this is a table with alternates in other keyspaces that we can use -func getRoutesOrAlternates(lhsRoute, rhsRoute *Route) (*Route, *Route, Routing, Routing, bool) { +func getRoutesOrAlternates(ctx *plancontext.PlanningContext, lhsRoute, rhsRoute *Route) (*Route, *Route, Routing, Routing, bool) { routingA := lhsRoute.Routing routingB := rhsRoute.Routing sameKeyspace := routingA.Keyspace() == routingB.Keyspace() @@ -171,13 +171,17 @@ func getRoutesOrAlternates(lhsRoute, rhsRoute *Route) (*Route, *Route, Routing, return lhsRoute, rhsRoute, routingA, routingB, sameKeyspace } - if refA, ok := routingA.(*AnyShardRouting); ok { + // If we have a reference route, we will try to find an alternate route in same keyspace as other routing keyspace. + // If the reference route is part of DML table update target, alternate keyspace route cannot be considered. + if refA, ok := routingA.(*AnyShardRouting); ok && + !TableID(lhsRoute).IsOverlapping(ctx.SemTable.DMLTargets) { if altARoute := refA.AlternateInKeyspace(routingB.Keyspace()); altARoute != nil { return altARoute, rhsRoute, altARoute.Routing, routingB, true } } - if refB, ok := routingB.(*AnyShardRouting); ok { + if refB, ok := routingB.(*AnyShardRouting); ok && + !TableID(rhsRoute).IsOverlapping(ctx.SemTable.DMLTargets) { if altBRoute := refB.AlternateInKeyspace(routingA.Keyspace()); altBRoute != nil { return lhsRoute, altBRoute, routingA, altBRoute.Routing, true } diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index 5fe0c7773c1..db716966d47 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -32,7 +32,7 @@ import ( func planQuery(ctx *plancontext.PlanningContext, root Operator) Operator { var selExpr sqlparser.SelectExprs if horizon, isHorizon := root.(*Horizon); isHorizon { - sel := sqlparser.GetFirstSelect(horizon.Query) + sel := getFirstSelect(horizon.Query) selExpr = sqlparser.Clone(sel.SelectExprs) } @@ -207,7 +207,7 @@ func pushOrExpandHorizon(ctx *plancontext.PlanningContext, in *Horizon) (Operato !hasHaving && !needsOrdering && !qp.NeedsAggregation() && - !in.selectStatement().IsDistinct() && + !isDistinctAST(in.selectStatement()) && in.selectStatement().GetLimit() == nil if canPush { @@ -784,7 +784,7 @@ func isDistinct(op Operator) bool { case *Union: return op.distinct case *Horizon: - return op.Query.IsDistinct() + return isDistinctAST(op.Query) case *Limit: return isDistinct(op.Source) default: @@ -792,6 +792,13 @@ func isDistinct(op Operator) bool { } } +func isDistinctAST(s sqlparser.Statement) bool { + if d, ok := s.(sqlparser.Distinctable); ok { + return d.IsDistinct() + } + return false +} + func tryPushUnion(ctx *plancontext.PlanningContext, op *Union) (Operator, *ApplyResult) { if res := compactUnion(op); res != NoRewrite { return op, res diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection.go b/go/vt/vtgate/planbuilder/operators/queryprojection.go index a245831ca13..c66bf757dd8 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection.go @@ -203,7 +203,7 @@ func (qp *QueryProjection) addSelectExpressions(ctx *plancontext.PlanningContext func createQPFromUnion(ctx *plancontext.PlanningContext, union *sqlparser.Union) *QueryProjection { qp := &QueryProjection{} - sel := sqlparser.GetFirstSelect(union) + sel := getFirstSelect(union) qp.addSelectExpressions(ctx, sel) qp.addOrderBy(ctx, union.OrderBy) @@ -714,7 +714,7 @@ func CompareRefInt(a *int, b *int) bool { return *a < *b } -func CreateQPFromSelectStatement(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement) *QueryProjection { +func CreateQPFromSelectStatement(ctx *plancontext.PlanningContext, stmt sqlparser.TableStatement) *QueryProjection { switch sel := stmt.(type) { case *sqlparser.Select: return createQPFromSelect(ctx, sel) diff --git a/go/vt/vtgate/planbuilder/operators/sharded_routing.go b/go/vt/vtgate/planbuilder/operators/sharded_routing.go index 066cb47d9a9..2c8873dee07 100644 --- a/go/vt/vtgate/planbuilder/operators/sharded_routing.go +++ b/go/vt/vtgate/planbuilder/operators/sharded_routing.go @@ -223,6 +223,9 @@ func (tr *ShardedRouting) resetRoutingLogic(ctx *plancontext.PlanningContext) Ro func (tr *ShardedRouting) searchForNewVindexes(ctx *plancontext.PlanningContext, predicate sqlparser.Expr) (Routing, bool) { newVindexFound := false switch node := predicate.(type) { + case *sqlparser.BetweenExpr: + return tr.planBetweenOp(ctx, node) + case *sqlparser.ComparisonExpr: return tr.planComparison(ctx, node) @@ -234,6 +237,35 @@ func (tr *ShardedRouting) searchForNewVindexes(ctx *plancontext.PlanningContext, return nil, newVindexFound } +func (tr *ShardedRouting) planBetweenOp(ctx *plancontext.PlanningContext, node *sqlparser.BetweenExpr) (routing Routing, foundNew bool) { + column, ok := node.Left.(*sqlparser.ColName) + if !ok { + return nil, false + } + var vdValue sqlparser.ValTuple = sqlparser.ValTuple([]sqlparser.Expr{node.From, node.To}) + + opcode := func(vindex *vindexes.ColumnVindex) engine.Opcode { + if _, ok := vindex.Vindex.(vindexes.Sequential); ok { + return engine.Between + } + return engine.Scatter + } + + sequentialVdx := func(vindex *vindexes.ColumnVindex) vindexes.Vindex { + if _, ok := vindex.Vindex.(vindexes.Sequential); ok { + return vindex.Vindex + } + // if vindex is not of type Sequential, we can't use this vindex at all + return nil + } + + val := makeEvalEngineExpr(ctx, vdValue) + if val == nil { + return nil, false + } + return nil, tr.haveMatchingVindex(ctx, node, vdValue, column, val, opcode, sequentialVdx) +} + func (tr *ShardedRouting) planComparison(ctx *plancontext.PlanningContext, cmp *sqlparser.ComparisonExpr) (routing Routing, foundNew bool) { switch cmp.Operator { case sqlparser.EqualOp: @@ -332,6 +364,8 @@ func (tr *ShardedRouting) Cost() int { return 5 case engine.IN: return 10 + case engine.Between: + return 10 case engine.MultiEqual: return 10 case engine.Scatter: @@ -441,6 +475,12 @@ func (tr *ShardedRouting) processMultiColumnVindex( return newVindexFound } + routeOpcode := opcode(v.ColVindex) + vindex := vfunc(v.ColVindex) + if vindex == nil || routeOpcode == engine.Scatter { + return newVindexFound + } + var newOption []*VindexOption for _, op := range v.Options { if op.Ready { diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index c2256df06f4..6ec5ecdd7f3 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -115,7 +115,7 @@ func createSubqueryOp( // inspectStatement goes through all the predicates contained in the AST // and extracts subqueries into operators func (sqb *SubQueryBuilder) inspectStatement(ctx *plancontext.PlanningContext, - stmt sqlparser.SelectStatement, + stmt sqlparser.TableStatement, ) (sqlparser.Exprs, []applyJoinColumn) { switch stmt := stmt.(type) { case *sqlparser.Select: diff --git a/go/vt/vtgate/planbuilder/operators/subquery_planning.go b/go/vt/vtgate/planbuilder/operators/subquery_planning.go index a2aca74fb6e..06ca69dd7f3 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_planning.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_planning.go @@ -30,7 +30,7 @@ import ( "vitess.io/vitess/go/vt/vtgate/semantics" ) -func isMergeable(ctx *plancontext.PlanningContext, query sqlparser.SelectStatement, op Operator) bool { +func isMergeable(ctx *plancontext.PlanningContext, query sqlparser.TableStatement, op Operator) bool { validVindex := func(expr sqlparser.Expr) bool { sc := findColumnVindex(ctx, op, expr) return sc != nil && sc.IsUnique() @@ -672,7 +672,7 @@ func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningCont if err != nil { panic(err) } - subqStmt, ok := stmt.(sqlparser.SelectStatement) + subqStmt, ok := stmt.(sqlparser.TableStatement) if !ok { panic(vterrors.VT13001("subqueries should only be select statement")) } @@ -700,7 +700,7 @@ func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningCont if !deps.IsSolvedBy(subqID) { cursor.Replace(exprFound) } - }, nil).(sqlparser.SelectStatement) + }, nil).(sqlparser.TableStatement) if err != nil { panic(err) } @@ -730,7 +730,7 @@ func mergeSubqueryInputs(ctx *plancontext.PlanningContext, in, out Operator, joi return nil } - inRoute, outRoute, inRouting, outRouting, sameKeyspace := getRoutesOrAlternates(inRoute, outRoute) + inRoute, outRoute, inRouting, outRouting, sameKeyspace := getRoutesOrAlternates(ctx, inRoute, outRoute) inner, outer := getRoutingType(inRouting), getRoutingType(outRouting) switch { diff --git a/go/vt/vtgate/planbuilder/operators/union.go b/go/vt/vtgate/planbuilder/operators/union.go index 7d09391cf7d..1c692c9f38e 100644 --- a/go/vt/vtgate/planbuilder/operators/union.go +++ b/go/vt/vtgate/planbuilder/operators/union.go @@ -150,7 +150,7 @@ func (u *Union) GetSelectFor(source int) *sqlparser.Select { for { switch op := src.(type) { case *Horizon: - return sqlparser.GetFirstSelect(op.Query) + return getFirstSelect(op.Query) case *Route: src = op.Source default: diff --git a/go/vt/vtgate/planbuilder/operators/union_merging.go b/go/vt/vtgate/planbuilder/operators/union_merging.go index 000d176b61a..6173b59e0dc 100644 --- a/go/vt/vtgate/planbuilder/operators/union_merging.go +++ b/go/vt/vtgate/planbuilder/operators/union_merging.go @@ -108,7 +108,7 @@ func mergeUnionInputs( lhsExprs, rhsExprs sqlparser.SelectExprs, distinct bool, ) (Operator, sqlparser.SelectExprs) { - lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(lhs, rhs) + lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(ctx, lhs, rhs) if lhsRoute == nil { return nil, nil } diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index dd0a86c2de2..18a81175f7b 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -164,7 +164,7 @@ func createUpdateWithInputOp(ctx *plancontext.PlanningContext, upd *sqlparser.Up ueMap := prepareUpdateExpressionList(ctx, upd) var updOps []dmlOp - for _, target := range ctx.SemTable.Targets.Constituents() { + for _, target := range ctx.SemTable.DMLTargets.Constituents() { op := createUpdateOpWithTarget(ctx, upd, target, ueMap[target]) updOps = append(updOps, op) } @@ -308,7 +308,7 @@ func errIfUpdateNotSupported(ctx *plancontext.PlanningContext, stmt *sqlparser.U } } - // Now we check if any of the foreign key columns that are being udpated have dependencies on other updated columns. + // Now we check if any of the foreign key columns that are being updated have dependencies on other updated columns. // This is unsafe, and we currently don't support this in Vitess. if err := ctx.SemTable.ErrIfFkDependentColumnUpdated(stmt.Exprs); err != nil { panic(err) diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index ccbc9821170..8a8d55279a6 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -84,6 +84,7 @@ func (s *planTestSuite) TestPlan() { s.addPKsProvided(vschema, "user", []string{"user_extra"}, []string{"id", "user_id"}) s.addPKsProvided(vschema, "ordering", []string{"order"}, []string{"oid", "region_id"}) s.addPKsProvided(vschema, "ordering", []string{"order_event"}, []string{"oid", "ename"}) + s.addPKsProvided(vschema, "main", []string{"source_of_ref"}, []string{"id"}) // You will notice that some tests expect user.Id instead of user.id. // This is because we now pre-create vindex columns in the symbol @@ -305,6 +306,7 @@ func (s *planTestSuite) TestOne() { s.addPKsProvided(vschema, "user", []string{"user_extra"}, []string{"id", "user_id"}) s.addPKsProvided(vschema, "ordering", []string{"order"}, []string{"oid", "region_id"}) s.addPKsProvided(vschema, "ordering", []string{"order_event"}, []string{"oid", "ename"}) + s.addPKsProvided(vschema, "main", []string{"source_of_ref"}, []string{"id"}) s.testFile("onecase.json", vw, false) } @@ -575,10 +577,10 @@ func (s *planTestSuite) TestOtherPlanningFromFile() { vw, err := vschemawrapper.NewVschemaWrapper(env, vschema, TestBuilder) require.NoError(s.T(), err) + s.testFile("other_read_cases.json", vw, false) + vw.Vcursor.SetTarget("main") vw.Keyspace = &vindexes.Keyspace{Name: "main"} - - s.testFile("other_read_cases.json", vw, false) s.testFile("other_admin_cases.json", vw, false) } @@ -649,21 +651,12 @@ func createFkDefinition(childCols []string, parentTableName string, parentCols [ } } -type ( - planTest struct { - Comment string `json:"comment,omitempty"` - Query string `json:"query,omitempty"` - Plan json.RawMessage `json:"plan,omitempty"` - Skip bool `json:"skip,omitempty"` - } -) - func (s *planTestSuite) testFile(filename string, vschema *vschemawrapper.VSchemaWrapper, render bool) { opts := jsondiff.DefaultConsoleOptions() s.T().Run(filename, func(t *testing.T) { failed := false - var expected []planTest + var expected []PlanTest for _, tcase := range readJSONTests(filename) { testName := tcase.Comment if testName == "" { @@ -672,9 +665,10 @@ func (s *planTestSuite) testFile(filename string, vschema *vschemawrapper.VSchem if tcase.Query == "" { continue } - current := planTest{ - Comment: testName, + current := PlanTest{ + Comment: tcase.Comment, Query: tcase.Query, + SkipE2E: tcase.SkipE2E, } vschema.Version = Gen4 out := getPlanOutput(tcase, vschema, render) @@ -720,8 +714,8 @@ func (s *planTestSuite) testFile(filename string, vschema *vschemawrapper.VSchem }) } -func readJSONTests(filename string) []planTest { - var output []planTest +func readJSONTests(filename string) []PlanTest { + var output []PlanTest file, err := os.Open(locateFile(filename)) if err != nil { panic(err) @@ -735,7 +729,7 @@ func readJSONTests(filename string) []planTest { return output } -func getPlanOutput(tcase planTest, vschema *vschemawrapper.VSchemaWrapper, render bool) (out string) { +func getPlanOutput(tcase PlanTest, vschema *vschemawrapper.VSchemaWrapper, render bool) (out string) { defer func() { if r := recover(); r != nil { out = fmt.Sprintf("panicked: %v\n%s", r, string(debug.Stack())) @@ -867,7 +861,7 @@ func BenchmarkBaselineVsMirrored(b *testing.B) { }) } -func benchmarkPlanner(b *testing.B, version plancontext.PlannerVersion, testCases []planTest, vschema *vschemawrapper.VSchemaWrapper) { +func benchmarkPlanner(b *testing.B, version plancontext.PlannerVersion, testCases []PlanTest, vschema *vschemawrapper.VSchemaWrapper) { b.ReportAllocs() for n := 0; n < b.N; n++ { for _, tcase := range testCases { diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go index e5e96b0a4be..2844f7e87dc 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go @@ -186,12 +186,17 @@ func createPlanContext(st *semantics.SemTable) *PlanningContext { type vschema struct{} +func (v *vschema) FindViewTarget(name sqlparser.TableName) (*vindexes.Keyspace, error) { + // TODO implement me + panic("implement me") +} + func (v *vschema) FindTable(tablename sqlparser.TableName) (*vindexes.Table, string, topodatapb.TabletType, key.Destination, error) { // TODO implement me panic("implement me") } -func (v *vschema) FindView(name sqlparser.TableName) sqlparser.SelectStatement { +func (v *vschema) FindView(name sqlparser.TableName) sqlparser.TableStatement { // TODO implement me panic("implement me") } diff --git a/go/vt/vtgate/planbuilder/plancontext/vschema.go b/go/vt/vtgate/planbuilder/plancontext/vschema.go index b4560424718..c810324f369 100644 --- a/go/vt/vtgate/planbuilder/plancontext/vschema.go +++ b/go/vt/vtgate/planbuilder/plancontext/vschema.go @@ -25,7 +25,9 @@ type PlannerVersion = querypb.ExecuteOptions_PlannerVersion // info about tables. type VSchema interface { FindTable(tablename sqlparser.TableName) (*vindexes.Table, string, topodatapb.TabletType, key.Destination, error) - FindView(name sqlparser.TableName) sqlparser.SelectStatement + FindView(name sqlparser.TableName) sqlparser.TableStatement + // FindViewTarget finds the target keyspace for the view table provided. + FindViewTarget(name sqlparser.TableName) (*vindexes.Keyspace, error) FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) // SelectedKeyspace returns the current keyspace if set, otherwise returns an error diff --git a/go/vt/vtgate/planbuilder/simplifier_test.go b/go/vt/vtgate/planbuilder/simplifier_test.go index dce21b3e175..5aeb0565f9b 100644 --- a/go/vt/vtgate/planbuilder/simplifier_test.go +++ b/go/vt/vtgate/planbuilder/simplifier_test.go @@ -49,7 +49,7 @@ func TestSimplifyBuggyQuery(t *testing.T) { reservedVars := sqlparser.NewReservedVars("vtg", reserved) simplified := simplifier.SimplifyStatement( - stmt.(sqlparser.SelectStatement), + stmt.(sqlparser.TableStatement), vw.CurrentDb(), vw, keepSameError(query, reservedVars, vw, rewritten.BindVarNeeds), @@ -73,7 +73,7 @@ func TestSimplifyPanic(t *testing.T) { reservedVars := sqlparser.NewReservedVars("vtg", reserved) simplified := simplifier.SimplifyStatement( - stmt.(sqlparser.SelectStatement), + stmt.(sqlparser.TableStatement), vw.CurrentDb(), vw, keepPanicking(query, reservedVars, vw, rewritten.BindVarNeeds), @@ -95,7 +95,7 @@ func TestUnsupportedFile(t *testing.T) { log.Errorf("unsupported_cases.txt - %s", tcase.Query) stmt, reserved, err := sqlparser.NewTestParser().Parse2(tcase.Query) require.NoError(t, err) - _, ok := stmt.(sqlparser.SelectStatement) + _, ok := stmt.(sqlparser.TableStatement) if !ok { t.Skip() return @@ -110,7 +110,7 @@ func TestUnsupportedFile(t *testing.T) { origQuery := sqlparser.String(ast) stmt, _, _ = sqlparser.NewTestParser().Parse2(tcase.Query) simplified := simplifier.SimplifyStatement( - stmt.(sqlparser.SelectStatement), + stmt.(sqlparser.TableStatement), vw.CurrentDb(), vw, keepSameError(tcase.Query, reservedVars, vw, rewritten.BindVarNeeds), @@ -128,7 +128,7 @@ func TestUnsupportedFile(t *testing.T) { } } -func keepSameError(query string, reservedVars *sqlparser.ReservedVars, vschema *vschemawrapper.VSchemaWrapper, needs *sqlparser.BindVarNeeds) func(statement sqlparser.SelectStatement) bool { +func keepSameError(query string, reservedVars *sqlparser.ReservedVars, vschema *vschemawrapper.VSchemaWrapper, needs *sqlparser.BindVarNeeds) func(statement sqlparser.TableStatement) bool { stmt, _, err := sqlparser.NewTestParser().Parse2(query) if err != nil { panic(err) @@ -139,7 +139,7 @@ func keepSameError(query string, reservedVars *sqlparser.ReservedVars, vschema * if expected == nil { panic("query does not fail to plan") } - return func(statement sqlparser.SelectStatement) bool { + return func(statement sqlparser.TableStatement) bool { _, myErr := BuildFromStmt(context.Background(), query, statement, reservedVars, vschema, needs, staticConfig{}) if myErr == nil { return false @@ -152,8 +152,8 @@ func keepSameError(query string, reservedVars *sqlparser.ReservedVars, vschema * } } -func keepPanicking(query string, reservedVars *sqlparser.ReservedVars, vschema *vschemawrapper.VSchemaWrapper, needs *sqlparser.BindVarNeeds) func(statement sqlparser.SelectStatement) bool { - cmp := func(statement sqlparser.SelectStatement) (res bool) { +func keepPanicking(query string, reservedVars *sqlparser.ReservedVars, vschema *vschemawrapper.VSchemaWrapper, needs *sqlparser.BindVarNeeds) func(statement sqlparser.TableStatement) bool { + cmp := func(statement sqlparser.TableStatement) (res bool) { defer func() { r := recover() if r != nil { @@ -172,7 +172,7 @@ func keepPanicking(query string, reservedVars *sqlparser.ReservedVars, vschema * if err != nil { panic(err.Error()) } - if !cmp(stmt.(sqlparser.SelectStatement)) { + if !cmp(stmt.(sqlparser.TableStatement)) { panic("query is not panicking") } diff --git a/go/vt/vtgate/planbuilder/test_helper.go b/go/vt/vtgate/planbuilder/test_helper.go new file mode 100644 index 00000000000..25d6b7306d1 --- /dev/null +++ b/go/vt/vtgate/planbuilder/test_helper.go @@ -0,0 +1,27 @@ +/* +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 planbuilder + +import "encoding/json" + +type PlanTest struct { + Comment string `json:"comment,omitempty"` + Query string `json:"query,omitempty"` + Plan json.RawMessage `json:"plan,omitempty"` + Skip bool `json:"skip,omitempty"` + SkipE2E bool `json:"skip_e2e,omitempty"` +} diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index 8b268e367dd..1ecbf3d4ff9 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -940,19 +940,44 @@ "Table": "`user`, user_extra" }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.`name` from music where 1 != 1", - "Query": "select music.`name` from music where music.id = :user_id", - "Table": "music", "Values": [ ":user_id" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.`name` from music where 1 != 1", + "Query": "select music.`name` from music where music.id = :user_id", + "Table": "music" + } + ] } ] } @@ -2992,19 +3017,44 @@ ] }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select 1 from music as m where 1 != 1", - "Query": "select 1 from music as m where m.id = :u2_val2", - "Table": "music", "Values": [ ":u2_val2" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from music as m where 1 != 1", + "Query": "select 1 from music as m where m.id = :u2_val2", + "Table": "music" + } + ] } ] } @@ -6110,6 +6160,44 @@ ] } }, + { + "comment": "last_insert_id on aggregation calculated at the vtgate level", + "query": "select last_insert_id(count(*)) from user", + "plan": { + "QueryType": "SELECT", + "Original": "select last_insert_id(count(*)) from user", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "last_insert_id(count(*)) as last_insert_id(count(*))" + ], + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Scalar", + "Aggregates": "sum_count_star(0) AS count(*)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FetchLastInsertID": true, + "FieldQuery": "select count(*) from `user` where 1 != 1", + "Query": "select count(*) from `user`", + "Table": "`user`" + } + ] + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } + }, { "comment": "aggregation on top of aggregation works fine", "query": "select distinct count(*) from user, (select distinct count(*) from user) X", diff --git a/go/vt/vtgate/planbuilder/testdata/bypass_keyrange_cases.json b/go/vt/vtgate/planbuilder/testdata/bypass_keyrange_cases.json index b13bafd77f8..e1ff7de97a0 100644 --- a/go/vt/vtgate/planbuilder/testdata/bypass_keyrange_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/bypass_keyrange_cases.json @@ -164,5 +164,22 @@ "Query": "create /* test */ table t1(id bigint, primary key(id)) /* comments */" } } + }, + { + "comment": "remove the matching keyspace from shard targeted query", + "query": "select count(*), col from `main`.unsharded join vt_main.t1 where exists (select 1 from main.t2 join information_schema.tables where table_name = 't3')", + "plan": { + "QueryType": "SELECT", + "Original": "select count(*), col from `main`.unsharded join vt_main.t1 where exists (select 1 from main.t2 join information_schema.tables where table_name = 't3')", + "Instructions": { + "OperatorType": "Send", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetDestination": "ExactKeyRange(-)", + "Query": "select count(*), col from unsharded join vt_main.t1 where exists (select 1 from t2 join information_schema.`tables` where table_name = 't3')" + } + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/bypass_shard_cases.json b/go/vt/vtgate/planbuilder/testdata/bypass_shard_cases.json index 02a00444724..80d4dbbd08b 100644 --- a/go/vt/vtgate/planbuilder/testdata/bypass_shard_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/bypass_shard_cases.json @@ -251,5 +251,22 @@ "QueryTimeout": 100 } } + }, + { + "comment": "remove the matching keyspace from shard targeted query", + "query": "select count(*), col from `main`.unsharded join vt_main.t1 where exists (select 1 from main.t2 join information_schema.tables where table_name = 't3')", + "plan": { + "QueryType": "SELECT", + "Original": "select count(*), col from `main`.unsharded join vt_main.t1 where exists (select 1 from main.t2 join information_schema.tables where table_name = 't3')", + "Instructions": { + "OperatorType": "Send", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetDestination": "Shard(-80)", + "Query": "select count(*), col from unsharded join vt_main.t1 where exists (select 1 from t2 join information_schema.`tables` where table_name = 't3')" + } + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index f796b935605..95cb14e38f5 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -2,12 +2,14 @@ { "comment": "update table not found", "query": "update nouser set val = 1", - "plan": "table nouser not found" + "plan": "table nouser not found", + "skip_e2e": true }, { "comment": "delete table not found", "query": "delete from nouser", - "plan": "table nouser not found" + "plan": "table nouser not found", + "skip_e2e": true }, { "comment": "explicit keyspace reference", @@ -29,7 +31,8 @@ "TablesUsed": [ "main.m1" ] - } + }, + "skip_e2e": true }, { "comment": "update unsharded", @@ -51,7 +54,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "subqueries in unsharded update", @@ -73,7 +77,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded union in subquery of unsharded update", @@ -95,7 +100,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded join in subquery of unsharded update", @@ -117,7 +123,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "update with join subquery", @@ -139,7 +146,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "routing rules: updated of a routed table", @@ -165,7 +173,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update: routing rules for subquery.", @@ -188,7 +197,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "delete unsharded", @@ -210,7 +220,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "delete from sequence", @@ -232,7 +243,8 @@ "TablesUsed": [ "main.seq" ] - } + }, + "skip_e2e": true }, { "comment": "delete from reference table in unsharded keyspace", @@ -254,7 +266,8 @@ "TablesUsed": [ "main.unsharded_ref" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id", @@ -280,7 +293,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id with alias", @@ -306,7 +320,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id with parenthesized expression", @@ -332,7 +347,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id with multi-part where clause with parens", @@ -358,7 +374,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing one vindex column", @@ -390,12 +407,14 @@ "TablesUsed": [ "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing same vindex twice", "query": "update user_metadata set email = 'a', email = 'b' where user_id = 1", - "plan": "VT03015: column has duplicate set values: 'email'" + "plan": "VT03015: column has duplicate set values: 'email'", + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing multiple vindex columns", @@ -428,7 +447,8 @@ "TablesUsed": [ "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing one vindex column, using order by and limit", @@ -460,7 +480,8 @@ "TablesUsed": [ "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "update changes non owned vindex column", @@ -492,7 +513,8 @@ "TablesUsed": [ "user.music_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, stray where clause", @@ -518,7 +540,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, stray where clause with conversion error", @@ -544,7 +567,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from by primary keyspace id", @@ -573,7 +597,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi-table delete with comma join", @@ -596,7 +621,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "multi-table delete with ansi join", @@ -619,7 +645,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "delete with join from subquery", @@ -641,7 +668,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "routing rules: deleted from a routed table", @@ -670,7 +698,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete: routing rules for subquery", @@ -693,7 +722,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "update by lookup", @@ -719,7 +749,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "update multi-table ansi join", @@ -742,7 +773,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "update multi-table comma join", @@ -765,7 +797,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "delete from by lookup", @@ -794,7 +827,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "delete from, no owned vindexes", @@ -820,7 +854,8 @@ "TablesUsed": [ "user.music_extra" ] - } + }, + "skip_e2e": true }, { "comment": "simple insert, no values", @@ -842,7 +877,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "simple insert unsharded", @@ -864,7 +900,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "simple upsert unsharded", @@ -886,7 +923,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert, no col list with auto-inc and authoritative column list", @@ -909,7 +947,8 @@ "TablesUsed": [ "main.unsharded_authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "sharded upsert with sharding key set to vindex column", @@ -936,7 +975,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "sharded bulk upsert with sharding key set to vindex column", @@ -963,7 +1003,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded with select", @@ -986,7 +1027,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded with select with join", @@ -1009,7 +1051,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, invalid value for auto-inc", @@ -1032,7 +1075,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, column present", @@ -1055,7 +1099,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, column absent", @@ -1078,7 +1123,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, column absent", @@ -1101,7 +1147,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, multi-val", @@ -1124,7 +1171,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert subquery in insert value", @@ -1146,7 +1194,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "sharded insert subquery in insert value", @@ -1174,7 +1223,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into a routed table", @@ -1202,12 +1252,14 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with mimatched column list", "query": "insert into user(id) values (1, 2)", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert no column list for sharded authoritative table", @@ -1232,7 +1284,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "insert sharded, no values", @@ -1260,7 +1313,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with one vindex", @@ -1288,7 +1342,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert ignore sharded", @@ -1317,7 +1372,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert on duplicate key", @@ -1346,7 +1402,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with one vindex and bind var", @@ -1374,7 +1431,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with non vindex", @@ -1402,7 +1460,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with default seq", @@ -1430,7 +1489,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with non vindex bool value", @@ -1458,7 +1518,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with all vindexes supplied", @@ -1486,7 +1547,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert for non-vindex autoinc", @@ -1512,7 +1574,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert for non-compliant names", @@ -1537,7 +1600,8 @@ "TablesUsed": [ "user.weird`name" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert from union", @@ -1560,7 +1624,8 @@ "main.dual", "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "insert for non-vindex autoinc, invalid value", @@ -1586,7 +1651,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert invalid index value", @@ -1612,17 +1678,20 @@ "TablesUsed": [ "user.music_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert invalid index value", "query": "insert into music_extra(music_id, user_id) values(1, id)", - "plan": "cannot lookup column 'id' (column access not supported here)" + "plan": "cannot lookup column 'id' (column access not supported here)", + "skip_e2e": true }, { "comment": "insert invalid table", "query": "insert into noexist(music_id, user_id) values(1, 18446744073709551616)", - "plan": "table noexist not found" + "plan": "table noexist not found", + "skip_e2e": true }, { "comment": "insert with multiple rows", @@ -1650,7 +1719,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with query timeout", @@ -1679,7 +1749,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with multiple rows - multi-shard autocommit", @@ -1708,12 +1779,14 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into a vindex not allowed", "query": "insert into user_index(id) values(1)", - "plan": "VT09014: vindex cannot be modified" + "plan": "VT09014: vindex cannot be modified", + "skip_e2e": true }, { "comment": "simple replace unsharded", @@ -1735,7 +1808,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded with select", @@ -1758,7 +1832,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, invalid value for auto-inc", @@ -1781,7 +1856,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, column present", @@ -1804,7 +1880,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, column absent", @@ -1827,7 +1904,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, multi-val", @@ -1850,12 +1928,14 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace invalid table", "query": "replace into noexist(music_id, user_id) values(1, 18446744073709551616)", - "plan": "table noexist not found" + "plan": "table noexist not found", + "skip_e2e": true }, { "comment": "insert a row in a multi column vindex table", @@ -1882,7 +1962,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "insert for overlapped vindex columns", @@ -1908,7 +1989,8 @@ "TablesUsed": [ "user.overlap_vindex" ] - } + }, + "skip_e2e": true }, { "comment": "insert multiple rows in a multi column vindex table", @@ -1935,7 +2017,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "delete row in a multi column vindex table", @@ -1964,7 +2047,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update columns of multi column vindex", @@ -1996,7 +2080,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update multiple vindexes, with multi column vindex", @@ -2029,7 +2114,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update with no primary vindex on where clause (scatter update)", @@ -2051,7 +2137,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with target destination", @@ -2073,7 +2160,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with no primary vindex on where clause (scatter update) - multi shard autocommit", @@ -2096,7 +2184,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with no primary vindex on where clause (scatter update) - query timeout", @@ -2119,7 +2208,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with non-comparison expr", @@ -2141,7 +2231,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with primary id through IN clause", @@ -2167,7 +2258,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with non-unique key", @@ -2189,7 +2281,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update by lookup with IN clause", @@ -2211,7 +2304,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with where clause with parens", @@ -2233,6 +2327,53 @@ "TablesUsed": [ "user.user_extra" ] + }, + "skip_e2e": true + }, + { + "comment": "update with last_insert_id in SET", + "query": "update user_extra set col = last_insert_id(123)", + "plan": { + "QueryType": "UPDATE", + "Original": "update user_extra set col = last_insert_id(123)", + "Instructions": { + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "FetchLastInsertID": true, + "Query": "update user_extra set col = last_insert_id(123)", + "Table": "user_extra" + }, + "TablesUsed": [ + "user.user_extra" + ] + } + }, + { + "comment": "delete with last_insert_id in where", + "query": "delete from user_extra where col = last_insert_id(123)", + "plan": { + "QueryType": "DELETE", + "Original": "delete from user_extra where col = last_insert_id(123)", + "Instructions": { + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "FetchLastInsertID": true, + "Query": "delete from user_extra where col = last_insert_id(123)", + "Table": "user_extra" + }, + "TablesUsed": [ + "user.user_extra" + ] } }, { @@ -2255,7 +2396,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete with target destination", @@ -2277,7 +2419,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete with non-comparison expr", @@ -2299,7 +2442,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with no index match", @@ -2321,7 +2465,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with no index match - multi shard autocommit", @@ -2344,7 +2489,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with no index match - query timeout", @@ -2367,7 +2513,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with primary id in through IN clause", @@ -2393,7 +2540,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded update where inner query references outer query", @@ -2417,7 +2565,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded delete where inner query references outer query", @@ -2440,7 +2589,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "update vindex value to null", @@ -2472,7 +2622,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using last_insert_id", @@ -2494,7 +2645,32 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true + }, + { + "comment": "insert using last_insert_id with argument (already an e2e test for this plan)", + "query": "insert into unsharded values(last_insert_id(789), 2)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into unsharded values(last_insert_id(789), 2)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "FetchLastInsertID": true, + "Query": "insert into unsharded values (last_insert_id(789), 2)", + "TableName": "unsharded" + }, + "TablesUsed": [ + "main.unsharded" + ] + }, + "skip_e2e": true }, { "comment": "update vindex value to null with multiple primary keyspace id", @@ -2526,7 +2702,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update vindex value to null without a where clause", @@ -2554,7 +2731,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update vindex value to null with complex where clause", @@ -2582,7 +2760,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from user by primary keyspace id with in clause", @@ -2611,7 +2790,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from user by complex expression", @@ -2636,7 +2816,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from user without a where clause", @@ -2661,7 +2842,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with single table targets", @@ -2690,7 +2872,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "scatter update table with owned vindexes without changing lookup vindex", @@ -2712,7 +2895,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "scatter delete with owned lookup vindex", @@ -2737,7 +2921,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update multi column vindex, without values for all the vindex columns", @@ -2769,7 +2954,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update with binary value", @@ -2801,7 +2987,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with binary value", @@ -2830,7 +3017,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with shard targeting", @@ -2855,7 +3043,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with shard targeting", @@ -2883,7 +3072,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with shard targeting without vindex", @@ -2905,7 +3095,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "multi-table delete with single table", @@ -2930,22 +3121,26 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with unknown reference", "query": "delete music from user where id = 1", - "plan": "VT03003: unknown table 'music' in MULTI DELETE" + "plan": "VT03003: unknown table 'music' in MULTI DELETE", + "skip_e2e": true }, { "comment": "delete with derived tables", "query": "delete music from (select * from user) music where id = 1", - "plan": "VT03004: the target table music of the DELETE is not updatable" + "plan": "VT03004: the target table music of the DELETE is not updatable", + "skip_e2e": true }, { "comment": "delete with derived tables with unknown table", "query": "delete user from (select * from user) music where id = 1", - "plan": "VT03003: unknown table 'user' in MULTI DELETE" + "plan": "VT03003: unknown table 'user' in MULTI DELETE", + "skip_e2e": true }, { "comment": "INSERT INTO main.user_privacy_consents (user_id, accepted_at) SELECT user_id, accepted_at FROM (SELECT 1 as user_id, 1629194864 as accepted_at) AS tmp WHERE NOT EXISTS (SELECT user_id FROM main.user_privacy_consents WHERE user_id = 1)", @@ -2968,7 +3163,8 @@ "main.dual", "main.user_privacy_consents" ] - } + }, + "skip_e2e": true }, { "comment": "Delete on backfilling unique lookup vindex should be a scatter", @@ -2993,7 +3189,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Update on backfilling unique lookup vindex should be a scatter", @@ -3021,7 +3218,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Delete on backfilling and non-backfilling unique lookup vindexes should be a delete equal", @@ -3050,7 +3248,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Update on backfilling and non-backfilling unique lookup vindexes should be an equal", @@ -3082,7 +3281,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Delete EQUAL and IN on backfilling and non-backfilling unique lookup vindexes should be a delete IN", @@ -3111,7 +3311,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Update EQUAL and IN on backfilling and non-backfilling unique lookup vindexes should be an update IN", @@ -3143,7 +3344,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "update with alias table", @@ -3171,7 +3373,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with alias table", @@ -3196,7 +3399,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex", @@ -3223,7 +3427,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex - reverse order", @@ -3250,7 +3455,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex using an IN clause", @@ -3277,7 +3483,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex using an IN clause", @@ -3304,7 +3511,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex", @@ -3334,7 +3542,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex - reverse order", @@ -3364,7 +3573,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex using an IN clause", @@ -3394,7 +3604,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex using an IN clause", @@ -3424,7 +3635,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with multicol and an owned vindex which changes", @@ -3457,7 +3669,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using non-unique lookup vindex", @@ -3483,7 +3696,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column", @@ -3509,7 +3723,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column on lookup vindex", @@ -3541,7 +3756,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column with in query", @@ -3573,7 +3789,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column with in query as lower cost over lookup vindex", @@ -3599,7 +3816,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using non-unique lookup vindex", @@ -3628,7 +3846,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using subsharding column", @@ -3657,7 +3876,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using subsharding column with in query", @@ -3686,7 +3906,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using subsharding column with in query as lower cost over lookup vindex", @@ -3715,7 +3936,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with simple table.", @@ -3754,22 +3976,26 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with more columns in insert", "query": "insert into music(id, user_id) select 1", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert using select with more columns in select", "query": "insert into music(id, user_id) select id, count(user_id), sum(user_id) from user group by id", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert using select with more columns in select after accounting for star column", "query": "insert into music(id, user_id) select id, *, 2 from user", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert using select with auto-inc column using vitess sequence, sequence column not present", @@ -3808,7 +4034,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with auto-inc column using vitess sequence, sequence column present", @@ -3847,7 +4074,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "sharded insert from select", @@ -3888,7 +4116,8 @@ "main.dual", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with sharding column is autoinc and not present in the insert column query", @@ -3929,12 +4158,14 @@ "main.dual", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with sharding column is not an autoinc and not present in the insert column query", "query": "insert into user_extra(pattern) SELECT 1", - "plan": "VT09003: INSERT query does not have primary vindex column 'user_id' in the column list" + "plan": "VT09003: INSERT query does not have primary vindex column 'user_id' in the column list", + "skip_e2e": true }, { "comment": "sharded same keyspace", @@ -3973,7 +4204,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded same keyspace", @@ -3996,7 +4228,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "sharded different keyspace", @@ -4035,7 +4268,8 @@ "user.user_extra", "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "sharded insert table, unsharded select table", @@ -4074,7 +4308,8 @@ "main_2.unsharded_tab", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded different keyspace", @@ -4109,7 +4344,8 @@ "main.unsharded", "main_2.unsharded_tab" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert table, sharded select table", @@ -4144,7 +4380,8 @@ "main.unsharded", "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded subquery in sharded update, not the same keyspace between outer and inner", @@ -4189,7 +4426,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in unsharded update, not the same keyspace", @@ -4234,7 +4472,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded join unsharded subqueries in unsharded update", @@ -4305,7 +4544,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded update with sub query where the sources can be merged into a single query", @@ -4332,7 +4572,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "merge through correlated subquery", @@ -4359,7 +4600,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "merge through correlated subquery #2", @@ -4382,7 +4624,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "all defaults empty column, empty values", @@ -4407,12 +4650,14 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "vexplain all dml without any directive should fail", "query": "vexplain all delete from user", - "plan": "VT09008: vexplain queries/all will actually run queries" + "plan": "VT09008: vexplain queries/all will actually run queries", + "skip_e2e": true }, { "comment": "vexplain dml with actually_run_query directive", @@ -4443,7 +4688,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "explain dml with actually_run_query directive - 2", @@ -4474,7 +4720,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with join from multi table join subquery", @@ -4497,7 +4744,8 @@ "main.unsharded", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using multi column vindex", @@ -4523,7 +4771,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using multi column vindex", @@ -4552,7 +4801,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into ref; TODO(maxeng) is this a bug?", @@ -4574,7 +4824,8 @@ "TablesUsed": [ "user.ref" ] - } + }, + "skip_e2e": true }, { "comment": "update using last_insert_id with an argument", @@ -4596,7 +4847,8 @@ "TablesUsed": [ "main.m1" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded update query with comment directive", @@ -4619,7 +4871,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert query with comment directive", @@ -4642,7 +4895,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "insert with select using same tables, cannot stream parallel", @@ -4685,7 +4939,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column - not provided", @@ -4712,7 +4967,8 @@ "TablesUsed": [ "user.mixed_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column - partially provided", @@ -4739,7 +4995,8 @@ "TablesUsed": [ "user.mixed_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column + select - not provided", @@ -4783,7 +5040,8 @@ "user.mixed_tbl", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column + select - provided", @@ -4827,12 +5085,14 @@ "user.mixed_tbl", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into a vindex not allowed", "query": "insert into user_index(id) values(1)", - "plan": "VT09014: vindex cannot be modified" + "plan": "VT09014: vindex cannot be modified", + "skip_e2e": true }, { "comment": "insert with select takes shared lock", @@ -4873,32 +5133,38 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Unsupported INSERT statement with a target destination", "query": "insert into `user[-]`.user_metadata (a, b) values (1,2)", - "plan": "VT09017: INSERT with a target destination is not allowed" + "plan": "VT09017: INSERT with a target destination is not allowed", + "skip_e2e": true }, { "comment": "Unsupported delete statement with a replica target destination", "query": "DELETE FROM `user[-]@replica`.user_metadata limit 1", - "plan": "VT09002: delete statement with a replica target" + "plan": "VT09002: delete statement with a replica target", + "skip_e2e": true }, { "comment": "Unsupported update statement with a replica target destination", "query": "update `user[-]@replica`.user_metadata set id=2", - "plan": "VT09002: update statement with a replica target" + "plan": "VT09002: update statement with a replica target", + "skip_e2e": true }, { "comment": "insert row values smaller than number of columns", "query": "insert into user(one, two, three, four) values (1, 2, 3)", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert row values greater than number of columns", "query": "insert into user(one, two, three) values (1, 2, 3, 4)", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert on duplicate key update with database qualifier", @@ -4925,7 +5191,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "delete from reference table - query send to source table", @@ -4947,7 +5214,8 @@ "TablesUsed": [ "main.source_of_ref" ] - } + }, + "skip_e2e": true }, { "comment": "delete from reference table - no source", @@ -4969,7 +5237,8 @@ "TablesUsed": [ "user.ref" ] - } + }, + "skip_e2e": true }, { "comment": "delete by target destination with limit", @@ -4994,7 +5263,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete sharded table with join with reference table", @@ -5020,7 +5290,8 @@ "user.ref_with_source", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete sharded table with join with another sharded table on vindex column", @@ -5046,7 +5317,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi delete multi table", @@ -5122,7 +5394,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "multi delete multi table with alias", @@ -5194,7 +5467,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "reverse the join order for delete", @@ -5266,7 +5540,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi table delete with join on vindex column", @@ -5292,7 +5567,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete 3 way join with sharding key and primary key same", @@ -5365,7 +5641,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete 3 way join with sharding key and primary key different", @@ -5438,7 +5715,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "sharded delete with limit clause", @@ -5493,7 +5771,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded delete with order by and limit clause", @@ -5549,7 +5828,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with limit clause", @@ -5601,7 +5881,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update a vindex column with limit", @@ -5659,7 +5940,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target", @@ -5738,7 +6020,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target modifying lookup vindex", @@ -5817,7 +6100,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target having dependent column update", @@ -5893,7 +6177,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target having multiple dependent column update", @@ -5969,7 +6254,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with multi target having dependent column update", @@ -6068,17 +6354,20 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table reference with multi target update on a derived table", "query": "update ignore (select foo, col, bar from user) u, music m set u.foo = 21, u.bar = 'abc' where u.col = m.col", - "plan": "VT03032: the target table (select foo, col, bar from `user`) as u of the UPDATE is not updatable" + "plan": "VT03032: the target table (select foo, col, bar from `user`) as u of the UPDATE is not updatable", + "skip_e2e": true }, { "comment": "update with derived table", "query": "update (select id from user) as u set id = 4", - "plan": "VT03032: the target table (select id from `user`) as u of the UPDATE is not updatable" + "plan": "VT03032: the target table (select id from `user`) as u of the UPDATE is not updatable", + "skip_e2e": true }, { "comment": "Delete with routed table on music", @@ -6103,7 +6392,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Update with routed table on music", @@ -6125,7 +6415,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Insert with routed table on music", @@ -6151,7 +6442,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in sharded delete", @@ -6207,7 +6499,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded subquery in sharded delete", @@ -6255,7 +6548,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in unsharded delete", @@ -6300,7 +6594,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in unsharded subquery in unsharded delete", @@ -6367,7 +6662,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded join unsharded subquery in unsharded delete", @@ -6438,7 +6734,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi target delete on sharded table", @@ -6530,7 +6827,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with multi-table targets", @@ -6625,7 +6923,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi table delete with 2 sharded tables join on vindex column", @@ -6694,7 +6993,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi table delete with 2 sharded tables join on non-vindex column", @@ -6785,7 +7085,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi target delete with composite primary key having single column vindex", @@ -6851,7 +7152,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "multi target delete with composite primary key with lookup vindex as sharding column", @@ -6917,7 +7219,8 @@ "ordering.order", "ordering.order_event" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table reference with multi target update", @@ -7002,7 +7305,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias in INSERT", @@ -7028,7 +7332,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias with explicit columns in INSERT", @@ -7054,7 +7359,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias in INSERT (no column list)", @@ -7080,7 +7386,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias with explicit columns in INSERT (no column list)", @@ -7106,6 +7413,7 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true } ] diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.json b/go/vt/vtgate/planbuilder/testdata/filter_cases.json index 4194a369bd6..72b6c4ddd46 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.json @@ -699,7 +699,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Composite IN: RHS not tuple", @@ -722,7 +723,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "Composite IN: RHS has no simple values", @@ -970,7 +972,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "Merging subqueries should remove keyspace from query", @@ -1095,7 +1098,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Multi-table unique vindex constraint", @@ -1252,7 +1256,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Multi-route unique vindex route on both routes", @@ -1279,7 +1284,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Multi-route with cross-route constraint", @@ -1328,7 +1334,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Multi-route with non-route constraint, should use first route.", @@ -1373,7 +1380,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Route with multiple route constraints, SelectIN is the best constraint.", @@ -1654,7 +1662,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "routing rules: choose the redirected table", @@ -1680,7 +1689,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "subquery", @@ -1729,7 +1739,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "correlated subquery merge-able into a route of a join tree", @@ -1778,7 +1789,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "ensure subquery reordering gets us a better plan", @@ -1824,7 +1836,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "nested subquery", @@ -1873,7 +1886,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Correlated subquery in where clause", @@ -1896,7 +1910,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "outer and inner subquery route by same int val", @@ -1923,7 +1938,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "outer and inner subquery route by same str val", @@ -1950,7 +1966,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "outer and inner subquery route by same val arg", @@ -1977,12 +1994,14 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "unresolved symbol in inner subquery.", "query": "select id from user where id = :a and user.col in (select user_extra.col from user_extra where user_extra.user_id = :a and foo.id = 1)", - "plan": "column 'foo.id' not found" + "plan": "column 'foo.id' not found", + "skip_e2e":true }, { "comment": "outer and inner subquery route by same outermost column value", @@ -2005,7 +2024,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "cross-shard subquery in IN clause.\n# Note the improved Underlying plan as SelectIN.", @@ -2290,7 +2310,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "routing rules subquery pullout", @@ -2339,7 +2360,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "Case preservation test", @@ -2366,7 +2388,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "database() call in where clause.", @@ -2649,7 +2672,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "solving LIKE query with a CFC prefix vindex", @@ -2701,7 +2725,8 @@ "TablesUsed": [ "user.samecolvin" ] - } + }, + "skip_e2e":true }, { "comment": "non unique predicate on vindex", @@ -2819,7 +2844,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "SelectDBA with uncorrelated subqueries", @@ -2838,7 +2864,8 @@ "Query": "select t.table_schema from information_schema.`tables` as t where t.table_schema in (select c.column_name from information_schema.`columns` as c)", "Table": "information_schema.`tables`" } - } + }, + "skip_e2e": true }, { "comment": "SelectReference with uncorrelated subqueries", @@ -3040,7 +3067,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "The outer and second inner are SelectEqualUnique with same Vindex value, the first inner has different Vindex value", @@ -3094,7 +3122,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "two correlated subqueries that can be merge in a single route", @@ -3117,7 +3146,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "transitive closures for the win", @@ -3166,7 +3196,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "not supported transitive closures with equality inside of an OR", @@ -3215,7 +3246,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "routing rules subquery merge with alias", @@ -3237,7 +3269,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "left join where clauses where we can optimize into an inner join", @@ -3282,12 +3315,14 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "this query lead to a nil pointer error", "query": "select user.id from user left join user_extra on user.col = user_extra.col where foo(user_extra.foobar)", - "plan": "expr cannot be translated, not supported: foo(user_extra.foobar)" + "plan": "expr cannot be translated, not supported: foo(user_extra.foobar)", + "skip_e2e" :true }, { "comment": "filter after outer join", @@ -3339,7 +3374,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "subquery on other table", @@ -3404,19 +3440,44 @@ "QueryType": "SELECT", "Original": "select * from multicolvin where column_b = 1", "Instructions": { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_b = 1", - "Table": "multicolvin", "Values": [ "1" ], - "Vindex": "colb_colc_map" + "Vindex": "colb_colc_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select colb, keyspace_id from colb_colc_map where 1 != 1", + "Query": "select colb, keyspace_id from colb_colc_map where colb in ::__vals", + "Table": "colb_colc_map", + "Values": [ + "::colb" + ], + "Vindex": "hash" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select * from multicolvin where 1 != 1", + "Query": "select * from multicolvin where column_b = 1", + "Table": "multicolvin" + } + ] }, "TablesUsed": [ "user.multicolvin" @@ -3430,19 +3491,44 @@ "QueryType": "SELECT", "Original": "select * from multicolvin where column_b = 1 and column_c = 2", "Instructions": { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_b = 1 and column_c = 2", - "Table": "multicolvin", "Values": [ "1" ], - "Vindex": "colb_colc_map" + "Vindex": "colb_colc_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select colb, keyspace_id from colb_colc_map where 1 != 1", + "Query": "select colb, keyspace_id from colb_colc_map where colb in ::__vals", + "Table": "colb_colc_map", + "Values": [ + "::colb" + ], + "Vindex": "hash" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select * from multicolvin where 1 != 1", + "Query": "select * from multicolvin where column_b = 1 and column_c = 2", + "Table": "multicolvin" + } + ] }, "TablesUsed": [ "user.multicolvin" @@ -3456,19 +3542,44 @@ "QueryType": "SELECT", "Original": "select * from multicolvin where column_b = 1 and column_c = 2 and column_a = 3", "Instructions": { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_b = 1 and column_c = 2 and column_a = 3", - "Table": "multicolvin", "Values": [ "1" ], - "Vindex": "colb_colc_map" + "Vindex": "colb_colc_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select colb, keyspace_id from colb_colc_map where 1 != 1", + "Query": "select colb, keyspace_id from colb_colc_map where colb in ::__vals", + "Table": "colb_colc_map", + "Values": [ + "::colb" + ], + "Vindex": "hash" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select * from multicolvin where 1 != 1", + "Query": "select * from multicolvin where column_b = 1 and column_c = 2 and column_a = 3", + "Table": "multicolvin" + } + ] }, "TablesUsed": [ "user.multicolvin" @@ -3482,19 +3593,44 @@ "QueryType": "SELECT", "Original": "select * from multicolvin where column_a = 3 and column_b = 1", "Instructions": { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_a = 3 and column_b = 1", - "Table": "multicolvin", "Values": [ "1" ], - "Vindex": "colb_colc_map" + "Vindex": "colb_colc_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select colb, keyspace_id from colb_colc_map where 1 != 1", + "Query": "select colb, keyspace_id from colb_colc_map where colb in ::__vals", + "Table": "colb_colc_map", + "Values": [ + "::colb" + ], + "Vindex": "hash" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select * from multicolvin where 1 != 1", + "Query": "select * from multicolvin where column_a = 3 and column_b = 1", + "Table": "multicolvin" + } + ] }, "TablesUsed": [ "user.multicolvin" @@ -3894,7 +4030,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "conditions following a null safe comparison operator can be used for routing", @@ -4344,7 +4481,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "two predicates that mean the same thing", @@ -4430,7 +4568,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "push filter under aggregation", @@ -4498,7 +4637,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "query that would time out because planning was too slow", @@ -4528,7 +4668,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "union inside subquery. all routes can be merged by literal value", @@ -4582,7 +4723,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "list args: single column vindex on non-zero offset", @@ -4608,7 +4750,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex", @@ -4635,7 +4778,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex - subshard", @@ -4661,7 +4805,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex - more columns", @@ -4688,7 +4833,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex - columns rearranged", @@ -4715,7 +4861,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "order by with filter removing the keyspace from order by", @@ -4820,5 +4967,148 @@ "user.authoritative" ] } + }, + { + "comment": "Between clause on primary indexed id column (binary vindex on id)", + "query": "select id from unq_binary_idx where id between 1 and 5", + "plan": { + "QueryType": "SELECT", + "Original": "select id from unq_binary_idx where id between 1 and 5", + "Instructions": { + "OperatorType": "Route", + "Variant": "Between", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id from unq_binary_idx where 1 != 1", + "Query": "select id from unq_binary_idx where id between 1 and 5", + "Table": "unq_binary_idx", + "Values": [ + "(1, 5)" + ], + "Vindex": "binary" + }, + "TablesUsed": [ + "user.unq_binary_idx" + ] + } + }, +{ + "comment": "Between clause on customer.id column (xxhash vindex on id)", + "query": "select id from customer where id between 1 and 5", + "plan": { + "QueryType": "SELECT", + "Original": "select id from customer where id between 1 and 5", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id from customer where 1 != 1", + "Query": "select id from customer where id between 1 and 5", + "Table": "customer" + }, + "TablesUsed": [ + "user.customer" + ] + } + }, +{ + "comment": "Between clause on col1 column (there is no vindex on this column)", + "query": "select id, col1 from unq_binary_idx where col1 between 10 and 50", + "plan": { + "QueryType": "SELECT", + "Original": "select id, col1 from unq_binary_idx where col1 between 10 and 50", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id, col1 from unq_binary_idx where 1 != 1", + "Query": "select id, col1 from unq_binary_idx where col1 between 10 and 50", + "Table": "unq_binary_idx" + }, + "TablesUsed": [ + "user.unq_binary_idx" + ] + } +}, +{ + "comment": "Between clause on multicolumn vindex (cola,colb)", + "query": "select cola,colb,colc from multicol_tbl where cola between 1 and 5", + "plan": { + "QueryType": "SELECT", + "Original": "select cola,colb,colc from multicol_tbl where cola between 1 and 5", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select cola, colb, colc from multicol_tbl where 1 != 1", + "Query": "select cola, colb, colc from multicol_tbl where cola between 1 and 5", + "Table": "multicol_tbl" + }, + "TablesUsed": [ + "user.multicol_tbl" + ] + } +}, +{ + "comment": "Between clause on a binary vindex field with values from a different table", + "query": "select s.oid,s.col1, se.colb from sales s join sales_extra se on s.col1 = se.cola where s.oid between se.start and se.end", + "plan": { + "QueryType": "SELECT", + "Original": "select s.oid,s.col1, se.colb from sales s join sales_extra se on s.col1 = se.cola where s.oid between se.start and se.end", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0,R:1,L:0", + "JoinVars": { + "se_cola": 1, + "se_end": 3, + "se_start": 2 + }, + "TableName": "sales_extra_sales", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select se.colb, se.cola, se.`start`, se.`end` from sales_extra as se where 1 != 1", + "Query": "select se.colb, se.cola, se.`start`, se.`end` from sales_extra as se", + "Table": "sales_extra" + }, + { + "OperatorType": "Route", + "Variant": "Between", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select s.oid, s.col1 from sales as s where 1 != 1", + "Query": "select s.oid, s.col1 from sales as s where s.oid between :se_start /* INT16 */ and :se_end /* INT16 */ and s.col1 = :se_cola /* VARCHAR */", + "Table": "sales", + "Values": [ + "(:se_start, :se_end)" + ], + "Vindex": "binary" + } + ] + }, + "TablesUsed": [ + "user.sales", + "user.sales_extra" + ] } +} ] diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.json b/go/vt/vtgate/planbuilder/testdata/from_cases.json index 2e0fe429c1f..bec64fd7b1e 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.json @@ -4709,19 +4709,44 @@ ] }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select 1 from music as m where 1 != 1", - "Query": "select 1 from music as m where m.user_id = 5 and m.id = 20 and m.col = :u_col /* INT16 */", - "Table": "music", "Values": [ "20" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from music as m where 1 != 1", + "Query": "select 1 from music as m where m.user_id = 5 and m.id = 20 and m.col = :u_col /* INT16 */", + "Table": "music" + } + ] } ] }, diff --git a/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json b/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json index 060f073a366..a35949cd4c1 100644 --- a/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json @@ -318,19 +318,44 @@ "Vindex": "user_index" }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.col3 as c, weight_string(music.col3) from music where 1 != 1", - "Query": "select music.col3 as c, weight_string(music.col3) from music where music.id = :user_id", - "Table": "music", "Values": [ ":user_id" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.col3 as c, weight_string(music.col3) from music where 1 != 1", + "Query": "select music.col3 as c, weight_string(music.col3) from music where music.id = :user_id", + "Table": "music" + } + ] } ] } @@ -379,19 +404,44 @@ "Vindex": "user_index" }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.col3, weight_string(music.col3) from music where 1 != 1", - "Query": "select music.col3, weight_string(music.col3) from music where music.id = :user_id", - "Table": "music", "Values": [ ":user_id" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.col3, weight_string(music.col3) from music where 1 != 1", + "Query": "select music.col3, weight_string(music.col3) from music where music.id = :user_id", + "Table": "music" + } + ] } ] } diff --git a/go/vt/vtgate/planbuilder/testdata/other_read_cases.json b/go/vt/vtgate/planbuilder/testdata/other_read_cases.json index 2258bcd768c..1a7c9ddac2a 100644 --- a/go/vt/vtgate/planbuilder/testdata/other_read_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/other_read_cases.json @@ -8,24 +8,24 @@ "Instructions": { "OperatorType": "Send", "Keyspace": { - "Name": "main", - "Sharded": false + "Name": "user", + "Sharded": true }, "TargetDestination": "AnyShard()", "Query": "explain select * from `user`", "SingleShardOnly": true }, "TablesUsed": [ - "main.user" + "user.user" ] } }, { "comment": "Analyze statement", - "query": "analyze table t1", + "query": "analyze table main.t1", "plan": { "QueryType": "ANALYZE", - "Original": "analyze table t1", + "Original": "analyze table main.t1", "Instructions": { "OperatorType": "Send", "Keyspace": { @@ -42,43 +42,43 @@ }, { "comment": "Describe statement", - "query": "describe select * from t", + "query": "describe select * from user", "plan": { "QueryType": "EXPLAIN", - "Original": "describe select * from t", + "Original": "describe select * from user", "Instructions": { "OperatorType": "Send", "Keyspace": { - "Name": "main", - "Sharded": false + "Name": "user", + "Sharded": true }, "TargetDestination": "AnyShard()", - "Query": "explain select * from t", + "Query": "explain select * from `user`", "SingleShardOnly": true }, "TablesUsed": [ - "main.t" + "user.user" ] } }, { "comment": "Desc statement", - "query": "desc select * from t", + "query": "desc select * from user", "plan": { "QueryType": "EXPLAIN", - "Original": "desc select * from t", + "Original": "desc select * from user", "Instructions": { "OperatorType": "Send", "Keyspace": { - "Name": "main", - "Sharded": false + "Name": "user", + "Sharded": true }, "TargetDestination": "AnyShard()", - "Query": "explain select * from t", + "Query": "explain select * from `user`", "SingleShardOnly": true }, "TablesUsed": [ - "main.t" + "user.user" ] } }, @@ -167,5 +167,31 @@ "main.administrable_role_authorizations" ] } + }, + { + "comment": "describe table without qualifier", + "query": "describe user", + "plan": { + "QueryType": "EXPLAIN", + "Original": "describe user", + "Instructions": { + "OperatorType": "Send", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "TargetDestination": "AnyShard()", + "Query": "explain `user`", + "SingleShardOnly": true + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "describe table does not exists", + "query": "describe unknown_table", + "plan": "table unknown_table not found" } ] diff --git a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json index 36f1472007d..6a8e94c0241 100644 --- a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json @@ -544,19 +544,44 @@ "Vindex": "user_index" }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id", - "Table": "music", "Values": [ ":user_id" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.col3 from music where 1 != 1", + "Query": "select music.col3 from music where music.id = :user_id", + "Table": "music" + } + ] } ] }, @@ -597,19 +622,44 @@ "Vindex": "user_index" }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id", - "Table": "music", "Values": [ ":user_id" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.col3 from music where 1 != 1", + "Query": "select music.col3 from music where music.id = :user_id", + "Table": "music" + } + ] } ] }, @@ -650,19 +700,44 @@ "Vindex": "user_index" }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id", - "Table": "music", "Values": [ ":user_id" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.col3 from music where 1 != 1", + "Query": "select music.col3 from music where music.id = :user_id", + "Table": "music" + } + ] } ] }, @@ -770,19 +845,44 @@ "Vindex": "user_index" }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id", - "Table": "music", "Values": [ ":user_id" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.col3 from music where 1 != 1", + "Query": "select music.col3 from music where music.id = :user_id", + "Table": "music" + } + ] } ] }, diff --git a/go/vt/vtgate/planbuilder/testdata/reference_cases.json b/go/vt/vtgate/planbuilder/testdata/reference_cases.json index 6aa01355934..1bf893beeef 100644 --- a/go/vt/vtgate/planbuilder/testdata/reference_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/reference_cases.json @@ -2,6 +2,7 @@ { "comment": "select from unqualified ambiguous reference routes to reference source", "query": "select * from ambiguous_ref_with_source", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select * from ambiguous_ref_with_source", @@ -24,6 +25,7 @@ { "comment": "join with unqualified ambiguous reference table routes to optimal keyspace", "query": "select user.col from user join ambiguous_ref_with_source", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select user.col from user join ambiguous_ref_with_source", @@ -47,6 +49,7 @@ { "comment": "ambiguous unqualified reference table self-join routes to reference source", "query": "select r1.col from ambiguous_ref_with_source r1 join ambiguous_ref_with_source", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select r1.col from ambiguous_ref_with_source r1 join ambiguous_ref_with_source", @@ -69,6 +72,7 @@ { "comment": "ambiguous unqualified reference table can merge with other opcodes left to right.", "query": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join user", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join user", @@ -92,6 +96,7 @@ { "comment": "ambiguous unqualified reference table can merge with other opcodes left to right and vindex value is in the plan", "query": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join (select aa from user where user.id=1) user", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join (select aa from user where user.id=1) user", @@ -119,6 +124,7 @@ { "comment": "qualified join to reference table routes to optimal keyspace", "query": "select user.col from user join main.ambiguous_ref_with_source", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select user.col from user join main.ambiguous_ref_with_source", @@ -142,6 +148,7 @@ { "comment": "insert into ambiguous unqualified reference table routes to source", "query": "insert into ambiguous_ref_with_source(col) values(1)", + "skip_e2e": true, "plan": { "QueryType": "INSERT", "Original": "insert into ambiguous_ref_with_source(col) values(1)", @@ -164,6 +171,7 @@ { "comment": "Reference tables using left join with a derived table having a limit clause", "query": "SELECT u.id FROM ( SELECT a.id, a.u_id FROM user.ref_with_source AS a WHERE a.id IN (3) ORDER BY a.d_at LIMIT 1) as u LEFT JOIN user.ref_with_source AS u0 ON u.u_id = u0.u_uid ORDER BY u.id", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "SELECT u.id FROM ( SELECT a.id, a.u_id FROM user.ref_with_source AS a WHERE a.id IN (3) ORDER BY a.d_at LIMIT 1) as u LEFT JOIN user.ref_with_source AS u0 ON u.u_id = u0.u_uid ORDER BY u.id", @@ -208,6 +216,7 @@ { "comment": "insert into qualified ambiguous reference table routes to source", "query": "insert into user.ambiguous_ref_with_source(col) values(1)", + "skip_e2e": true, "plan": { "QueryType": "INSERT", "Original": "insert into user.ambiguous_ref_with_source(col) values(1)", @@ -230,6 +239,7 @@ { "comment": "update unqualified ambiguous reference table routes to source", "query": "update ambiguous_ref_with_source set col = 1", + "skip_e2e": true, "plan": { "QueryType": "UPDATE", "Original": "update ambiguous_ref_with_source set col = 1", @@ -252,6 +262,7 @@ { "comment": "update qualified ambiguous reference table route to source", "query": "update user.ambiguous_ref_with_source set col = 1", + "skip_e2e": true, "plan": { "QueryType": "UPDATE", "Original": "update user.ambiguous_ref_with_source set col = 1", @@ -274,6 +285,7 @@ { "comment": "delete from unqualified ambiguous reference table routes to source", "query": "delete from ambiguous_ref_with_source where col = 1", + "skip_e2e": true, "plan": { "QueryType": "DELETE", "Original": "delete from ambiguous_ref_with_source where col = 1", @@ -296,6 +308,7 @@ { "comment": "delete from qualified ambiguous reference table route to source", "query": "delete from user.ambiguous_ref_with_source where col = 1", + "skip_e2e": true, "plan": { "QueryType": "DELETE", "Original": "delete from user.ambiguous_ref_with_source where col = 1", @@ -318,6 +331,7 @@ { "comment": "join with unqualified unambiguous ref with source routes to requested table", "query": "select user.col from user join ref_with_source", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select user.col from user join ref_with_source", @@ -341,6 +355,7 @@ { "comment": "join with unqualified reference optimize routes when source & reference have different names", "query": "select user.col from user join source_of_ref", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select user.col from user join source_of_ref", @@ -364,6 +379,7 @@ { "comment": "join with unqualified reference respects routing rules", "query": "select user.col from user join rerouted_ref", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select user.col from user join rerouted_ref", @@ -387,6 +403,7 @@ { "comment": "join with reference to unqualified source routes to optimal keyspace", "query": "select user.col from user join global_ref", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select user.col from user join global_ref", @@ -410,6 +427,7 @@ { "comment": "insert into qualified reference with unqualified source routes to source", "query": "insert into user.global_ref(col) values(1)", + "skip_e2e": true, "plan": { "QueryType": "INSERT", "Original": "insert into user.global_ref(col) values(1)", @@ -432,6 +450,7 @@ { "comment": "delete from reference table with another name - query send to source table", "query": "delete from user.ref_with_source where col = 1", + "skip_e2e": true, "plan": { "QueryType": "DELETE", "Original": "delete from user.ref_with_source where col = 1", @@ -454,6 +473,7 @@ { "comment": "update from reference table with another name - query send to source table", "query": "update user.ref_with_source set x = 4 where col = 1", + "skip_e2e": true, "plan": { "QueryType": "UPDATE", "Original": "update user.ref_with_source set x = 4 where col = 1", @@ -476,6 +496,7 @@ { "comment": "insert from reference table with another name - query send to source table", "query": "insert into user.ref_with_source(x) values(4)", + "skip_e2e": true, "plan": { "QueryType": "INSERT", "Original": "insert into user.ref_with_source(x) values(4)", @@ -498,6 +519,7 @@ { "comment": "delete from reference table - query send to source table", "query": "delete from source_of_ref where col = 1", + "skip_e2e": true, "plan": { "QueryType": "DELETE", "Original": "delete from source_of_ref where col = 1", @@ -520,6 +542,7 @@ { "comment": "update from reference table - query send to source table", "query": "update source_of_ref set x = 4 where col = 1", + "skip_e2e": true, "plan": { "QueryType": "UPDATE", "Original": "update source_of_ref set x = 4 where col = 1", @@ -542,6 +565,7 @@ { "comment": "insert from reference table - query send to source table", "query": "insert into source_of_ref(x) values(4)", + "skip_e2e": true, "plan": { "QueryType": "INSERT", "Original": "insert into source_of_ref(x) values(4)", @@ -564,6 +588,7 @@ { "comment": "delete from reference table qualified with unsharded - query send to source table", "query": "delete from main.source_of_ref where col = 1", + "skip_e2e": true, "plan": { "QueryType": "DELETE", "Original": "delete from main.source_of_ref where col = 1", @@ -586,6 +611,7 @@ { "comment": "update from reference table qualified with unsharded - query send to source table", "query": "update main.source_of_ref set x = 4 where col = 1", + "skip_e2e": true, "plan": { "QueryType": "UPDATE", "Original": "update main.source_of_ref set x = 4 where col = 1", @@ -608,6 +634,7 @@ { "comment": "insert from reference table qualified with unsharded - query send to source table", "query": "insert into main.source_of_ref(x) values(4)", + "skip_e2e": true, "plan": { "QueryType": "INSERT", "Original": "insert into main.source_of_ref(x) values(4)", @@ -630,6 +657,7 @@ { "comment": "delete from reference table with another name - query send to source table", "query": "delete from user.ref_with_source where col = 1", + "skip_e2e": true, "plan": { "QueryType": "DELETE", "Original": "delete from user.ref_with_source where col = 1", @@ -652,6 +680,7 @@ { "comment": "update from reference table with another name - query send to source table", "query": "update user.ref_with_source set x = 4 where col = 1", + "skip_e2e": true, "plan": { "QueryType": "UPDATE", "Original": "update user.ref_with_source set x = 4 where col = 1", @@ -674,6 +703,7 @@ { "comment": "insert from reference table with another name - query send to source table", "query": "insert into user.ref_with_source(x) values(4)", + "skip_e2e": true, "plan": { "QueryType": "INSERT", "Original": "insert into user.ref_with_source(x) values(4)", @@ -696,6 +726,7 @@ { "comment": "select with join to reference table in sharded keyspace: should route shard-scoped", "query": "select * from user.ref_with_source ref, `user`.`user` u where ref.id = u.ref_id and u.id = 2", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select * from user.ref_with_source ref, `user`.`user` u where ref.id = u.ref_id and u.id = 2", @@ -723,6 +754,7 @@ { "comment": "select with join to reference table in unsharded keyspace: should route shard-scoped", "query": "select * from source_of_ref ref, `user`.`user` u where ref.id = u.ref_id and u.id = 2", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select * from source_of_ref ref, `user`.`user` u where ref.id = u.ref_id and u.id = 2", @@ -750,6 +782,7 @@ { "comment": "two sharded and two unsharded reference table join - all should be merged into one route", "query": "select 1 from user u join user_extra ue on u.id = ue.user_id join main.source_of_ref sr on sr.foo = ue.foo join main.rerouted_ref rr on rr.bar = sr.bar", + "skip_e2e": true, "plan": { "QueryType": "SELECT", "Original": "select 1 from user u join user_extra ue on u.id = ue.user_id join main.source_of_ref sr on sr.foo = ue.foo join main.rerouted_ref rr on rr.bar = sr.bar", @@ -771,5 +804,145 @@ "user.user_extra" ] } + }, + { + "comment": "update reference table with join on sharded table", + "query": "update main.source_of_ref as sr join main.rerouted_ref as rr on sr.id = rr.id inner join user.music as m on sr.col = m.col set sr.tt = 5 where m.user_id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update main.source_of_ref as sr join main.rerouted_ref as rr on sr.id = rr.id inner join user.music as m on sr.col = m.col set sr.tt = 5 where m.user_id = 1", + "Instructions": { + "OperatorType": "DMLWithInput", + "TargetTabletType": "PRIMARY", + "Offset": [ + "0:[0]" + ], + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0", + "JoinVars": { + "m_col": 0 + }, + "TableName": "music_rerouted_ref, source_of_ref", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select m.col from music as m where 1 != 1", + "Query": "select m.col from music as m where m.user_id = 1 lock in share mode", + "Table": "music", + "Values": [ + "1" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select sr.id from source_of_ref as sr, rerouted_ref as rr where 1 != 1", + "Query": "select sr.id from source_of_ref as sr, rerouted_ref as rr where sr.col = :m_col and sr.id = rr.id lock in share mode", + "Table": "rerouted_ref, source_of_ref" + } + ] + }, + { + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update source_of_ref as sr set sr.tt = 5 where sr.id in ::dml_vals", + "Table": "source_of_ref" + } + ] + }, + "TablesUsed": [ + "main.rerouted_ref", + "main.source_of_ref", + "user.music" + ] + } + }, + { + "comment": "delete from reference table with join on sharded table", + "query": "delete sr from main.source_of_ref as sr join main.rerouted_ref as rr on sr.id = rr.id inner join user.music as m on sr.col = m.col where m.user_id = 1", + "plan": { + "QueryType": "DELETE", + "Original": "delete sr from main.source_of_ref as sr join main.rerouted_ref as rr on sr.id = rr.id inner join user.music as m on sr.col = m.col where m.user_id = 1", + "Instructions": { + "OperatorType": "DMLWithInput", + "TargetTabletType": "PRIMARY", + "Offset": [ + "0:[0]" + ], + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0", + "JoinVars": { + "m_col": 0 + }, + "TableName": "music_rerouted_ref, source_of_ref", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select m.col from music as m where 1 != 1", + "Query": "select m.col from music as m where m.user_id = 1", + "Table": "music", + "Values": [ + "1" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select sr.id from source_of_ref as sr, rerouted_ref as rr where 1 != 1", + "Query": "select sr.id from source_of_ref as sr, rerouted_ref as rr where sr.col = :m_col and sr.id = rr.id", + "Table": "rerouted_ref, source_of_ref" + } + ] + }, + { + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete from source_of_ref as sr where sr.id in ::dml_vals", + "Table": "source_of_ref" + } + ] + }, + "TablesUsed": [ + "main.rerouted_ref", + "main.source_of_ref", + "user.music" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/sampledata/user.sql b/go/vt/vtgate/planbuilder/testdata/sampledata/user.sql new file mode 100644 index 00000000000..ff1afd68fca --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/sampledata/user.sql @@ -0,0 +1,23 @@ +INSERT INTO sales (oid, col1) + VALUES (1, 'a_1'); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (11, 'a_1', 'b_1',0, 500); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (12, 'a_2', 'b_2',500, 1000); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (13, 'a_3', 'b_3',1000, 1500); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (14, 'a_4', 'b_4',1500, 2000); + +INSERT INTO music (id, user_id, col) +VALUES (100, 1, 'foo'); + +INSERT INTO source_of_ref (id, col, tt) +VALUES (200, 'foo', 2); + +INSERT INTO rerouted_ref (id, ref_col, name) +VALUES (200, 'bar', 'baz'); \ No newline at end of file diff --git a/go/vt/vtgate/planbuilder/testdata/schemas/main.sql b/go/vt/vtgate/planbuilder/testdata/schemas/main.sql new file mode 100644 index 00000000000..e615871cf2b --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/schemas/main.sql @@ -0,0 +1,44 @@ +CREATE TABLE `unsharded` +( + `id` INT NOT NULL PRIMARY KEY, + `col` VARCHAR(255) DEFAULT NULL, + `col1` VARCHAR(255) DEFAULT NULL, + `col2` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL, + `baz` INT +); + +CREATE TABLE `unsharded_auto` +( + `id` INT NOT NULL PRIMARY KEY, + `col1` VARCHAR(255) DEFAULT NULL, + `col2` VARCHAR(255) DEFAULT NULL +); + +CREATE TABLE `unsharded_a` +( + `id` INT NOT NULL PRIMARY KEY, + `col` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL +); + +CREATE TABLE `unsharded_b` +( + `id` INT NOT NULL PRIMARY KEY, + `col` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL +); + +CREATE TABLE `source_of_ref` +( + `id` INT NOT NULL PRIMARY KEY, + `col` VARCHAR(255) DEFAULT NULL, + `tt` BIGINT DEFAULT NULL +); + +CREATE TABLE `rerouted_ref` +( + `id` INT NOT NULL PRIMARY KEY, + `ref_col` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL +); \ No newline at end of file diff --git a/go/vt/vtgate/planbuilder/testdata/schemas/user.sql b/go/vt/vtgate/planbuilder/testdata/schemas/user.sql new file mode 100644 index 00000000000..10c1886a992 --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/schemas/user.sql @@ -0,0 +1,188 @@ +CREATE TABLE user +( + id INT PRIMARY KEY, + col BIGINT, + intcol BIGINT, + user_id INT, + id1 INT, + id2 INT, + id3 INT, + m INT, + bar INT, + a INT, + name VARCHAR(255), + col1 VARCHAR(255), + col2 VARCHAR(255), + costly VARCHAR(255), + predef1 VARCHAR(255), + predef2 VARCHAR(255), + textcol1 VARCHAR(255), + textcol2 VARCHAR(255), + someColumn VARCHAR(255), + foo VARCHAR(255) +); + +CREATE TABLE user_metadata +( + user_id INT, + email VARCHAR(255), + address VARCHAR(255), + md5 VARCHAR(255), + non_planable VARCHAR(255), + PRIMARY KEY (user_id) +); + +CREATE TABLE music +( + user_id INT, + id INT, + col VARCHAR(255), + col1 VARCHAR(255), + col2 VARCHAR(255), + genre VARCHAR(255), + componist VARCHAR(255), + PRIMARY KEY (user_id) +); + +CREATE TABLE name_user_vdx +( + name INT, + keyspace_id VARBINARY(10), + primary key (name) +); + +CREATE TABLE samecolvin +( + col VARCHAR(255), + PRIMARY KEY (col) +); + +CREATE TABLE multicolvin +( + kid INT, + column_a INT, + column_b INT, + column_c INT, + PRIMARY KEY (kid) +); + +CREATE TABLE customer +( + id INT, + email VARCHAR(255), + phone VARCHAR(255), + PRIMARY KEY (id) +); + +CREATE TABLE multicol_tbl +( + cola VARCHAR(255), + colb VARCHAR(255), + colc VARCHAR(255), + name VARCHAR(255), + PRIMARY KEY (cola, colb) +); + +CREATE TABLE mixed_tbl +( + shard_key VARCHAR(255), + lkp_key VARCHAR(255), + PRIMARY KEY (shard_key) +); + +CREATE TABLE pin_test +( + id INT PRIMARY KEY +); + +CREATE TABLE cfc_vindex_col +( + c1 VARCHAR(255), + c2 VARCHAR(255), + PRIMARY KEY (c1) +); + +CREATE TABLE unq_lkp_idx +( + unq_key INT PRIMARY KEY, + keyspace_id VARCHAR(255) +); + +CREATE TABLE t1 +( + c1 INT, + c2 INT, + c3 INT, + PRIMARY KEY (c1) +); + +CREATE TABLE authoritative +( + user_id bigint NOT NULL, + col1 VARCHAR(255), + col2 bigint, + PRIMARY KEY (user_id) +) ENGINE=InnoDB; + +CREATE TABLE colb_colc_map +( + colb INT PRIMARY KEY, + colc INT, + keyspace_id VARCHAR(255) +); + +CREATE TABLE seq +( + id INT, + next_id BIGINT, + cache BIGINT, + PRIMARY KEY (id) +) COMMENT 'vitess_sequence'; + +CREATE TABLE user_extra +( + id INT, + user_id INT, + extra_id INT, + col INT, + m2 INT, + PRIMARY KEY (id, extra_id) +); + +CREATE TABLE name_user_map +( + name VARCHAR(255), + keyspace_id VARCHAR(255) +); + +CREATE TABLE costly_map +( + costly VARCHAR(255), + keyspace_id VARCHAR(255) +); + +CREATE TABLE unq_binary_idx +( + id INT PRIMARY KEY, + col1 INT +); + +CREATE TABLE sales +( + oid INT PRIMARY KEY, + col1 VARCHAR(255) +); + +CREATE TABLE sales_extra +( + colx INT PRIMARY KEY, + cola VARCHAR(255), + colb VARCHAR(255), + start INT, + end INT +); + +CREATE TABLE ref +( + col INT PRIMARY KEY +); \ No newline at end of file diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index ab69df2cc47..e18fa274d7e 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -92,7 +92,8 @@ "user.user", "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "select with timeout directive sets QueryTimeout in the route", @@ -197,7 +198,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "select with partial scatter directive", @@ -402,7 +404,8 @@ { "comment": "test table lookup failure for authoritative code path", "query": "select a.* from authoritative", - "plan": "Unknown table 'a'" + "plan": "Unknown table 'a'", + "skip_e2e": true }, { "comment": "select * from qualified authoritative table", @@ -470,7 +473,8 @@ "user.authoritative", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "auto-resolve anonymous columns for simple route", @@ -493,7 +497,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "json_arrayagg in single sharded query", @@ -519,7 +524,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "json_objectagg in single sharded query", @@ -545,17 +551,20 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "unsupported json aggregation expressions in scatter query", "query": "select count(1) from user where cola = 'abc' group by n_id having json_arrayagg(a_id) = '[]'", - "plan": "VT12001: unsupported: in scatter query: aggregation function 'json_arrayagg(a_id)'" + "plan": "VT12001: unsupported: in scatter query: aggregation function 'json_arrayagg(a_id)'", + "skip_e2e": true }, { "comment": "Cannot auto-resolve for cross-shard joins", "query": "select col from user join user_extra", - "plan": "Column 'col' in field list is ambiguous" + "plan": "Column 'col' in field list is ambiguous", + "skip_e2e": true }, { "comment": "Auto-resolve should work if unique vindex columns are referenced", @@ -597,7 +606,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "database calls should be substituted", @@ -619,7 +629,8 @@ "TablesUsed": [ "main.dual" ] - } + }, + "skip_e2e": true }, { "comment": "last_insert_id for unsharded route", @@ -641,7 +652,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "select from dual on unqualified keyspace", @@ -694,7 +706,8 @@ { "comment": "prefixing dual with a keyspace should not work", "query": "select 1 from user.dual", - "plan": "table dual not found" + "plan": "table dual not found", + "skip_e2e": true }, { "comment": "RHS route referenced", @@ -736,7 +749,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Both routes referenced", @@ -778,7 +792,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Expression with single-route reference", @@ -820,7 +835,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "subquery with an aggregation in order by that can be merged into a single route", @@ -847,7 +863,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Jumbled references", @@ -889,7 +906,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Comments", @@ -931,7 +949,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "for update", @@ -973,7 +992,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Field query should work for joins select bind vars", @@ -1018,7 +1038,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Case preservation", @@ -1060,12 +1081,14 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "syntax error", "query": "the quick brown fox", - "plan": "syntax error at position 4 near 'the'" + "plan": "syntax error at position 4 near 'the'", + "skip_e2e": true }, { "comment": "Hex number is not treated as a simple value", @@ -1113,7 +1136,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Selection but make the planner explicitly use a vindex", @@ -1164,12 +1188,14 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Vindex hint on a non-existing vindex", "query": "select * from user use vindex (does_not_exist) where id = 1", - "plan": "VT09021: Vindex 'does_not_exist' does not exist in table 'user.user'" + "plan": "VT09021: Vindex 'does_not_exist' does not exist in table 'user.user'", + "skip_e2e": true }, { "comment": "sharded limit offset", @@ -1231,7 +1257,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Sharding Key Condition in Parenthesis", @@ -1257,7 +1284,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Multiple parenthesized expressions", @@ -1283,7 +1311,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Multiple parenthesized expressions", @@ -1309,7 +1338,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Column Aliasing with Table.Column", @@ -1387,7 +1417,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Column as boolean-ish", @@ -1413,7 +1444,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "PK as fake boolean, and column as boolean-ish", @@ -1439,7 +1471,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "top level subquery in select", @@ -1484,7 +1517,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sub-expression subquery in select", @@ -1529,7 +1563,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "select * from derived table expands specific columns", @@ -1571,17 +1606,20 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "duplicate columns not allowed in derived table", "query": "select * from (select user.id, user_extra.id from user join user_extra) as t", - "plan": "Duplicate column name 'id'" + "plan": "Duplicate column name 'id'", + "skip_e2e": true }, { "comment": "non-existent symbol in cross-shard derived table", "query": "select t.col from (select user.id from user join user_extra) as t", - "plan": "column 't.col' not found" + "plan": "column 't.col' not found", + "skip_e2e": true }, { "comment": "union with the same target shard", @@ -1608,7 +1646,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "union with the same target shard last_insert_id", @@ -1635,7 +1674,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded union in derived table", @@ -1793,7 +1833,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "routing table on music", @@ -1815,7 +1856,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "testing SingleRow Projection", @@ -1962,7 +2004,8 @@ "main.unsharded_a", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Complex expression in a subquery used in NOT IN clause of an aggregate query", @@ -2015,7 +2058,8 @@ "main.unsharded_a", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "testing SingleRow Projection with arithmetics", @@ -2218,12 +2262,14 @@ { "comment": "sql_calc_found_rows in sub queries", "query": "select * from music where user_id IN (select sql_calc_found_rows * from music limit 10)", - "plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'" + "plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'", + "skip_e2e": true }, { "comment": "sql_calc_found_rows in derived table", "query": "select sql_calc_found_rows * from (select sql_calc_found_rows * from music limit 10) t limit 1", - "plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'" + "plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'", + "skip_e2e": true }, { "comment": "select from unsharded keyspace into dumpfile", @@ -2245,7 +2291,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "select from unsharded keyspace into outfile", @@ -2267,7 +2314,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "select from unsharded keyspace into outfile s3", @@ -2289,7 +2337,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "left join with a dual table on left - merge-able", @@ -2500,17 +2549,20 @@ { "comment": "Union after into outfile is incorrect", "query": "select id from user into outfile 'out_file_name' union all select id from music", - "plan": "syntax error at position 55 near 'union'" + "plan": "syntax error at position 55 near 'union'", + "skip_e2e": true }, { "comment": "Into outfile s3 in derived table is incorrect", "query": "select id from (select id from user into outfile s3 'inner_outfile') as t2", - "plan": "syntax error at position 41 near 'into'" + "plan": "syntax error at position 41 near 'into'", + "skip_e2e": true }, { "comment": "Into outfile s3 in derived table with union incorrect", "query": "select id from (select id from user into outfile s3 'inner_outfile' union select 1) as t2", - "plan": "syntax error at position 41 near 'into'" + "plan": "syntax error at position 41 near 'into'", + "skip_e2e": true }, { "comment": "select (select u.id from user as u where u.id = 1), a.id from user as a where a.id = 1", @@ -2579,7 +2631,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "((((select 1))))", @@ -2624,7 +2677,8 @@ "main.dual", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "subquery in select expression of derived table", @@ -2694,7 +2748,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "ORDER BY subquery", @@ -2764,7 +2819,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "plan test for a natural character set string", @@ -2831,7 +2887,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Straight Join ensures specific ordering of joins", @@ -2876,7 +2933,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Dual query should be handled on the vtgate even with a LIMIT", @@ -2950,7 +3008,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Straight Join preserved in MySQL query", @@ -2973,7 +3032,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "correlated subquery in exists clause", @@ -3031,7 +3091,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "correlated subquery in exists clause with an order by", @@ -3090,7 +3151,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "correlated subquery having dependencies on two tables", @@ -3163,7 +3225,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "correlated subquery using a column twice", @@ -3220,7 +3283,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "correlated subquery that is dependent on one side of a join, fully mergeable", @@ -3271,7 +3335,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "union as a derived table", @@ -3360,7 +3425,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "mergeable derived table with order by and limit", @@ -3382,7 +3448,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "mergeable derived table with group by and limit", @@ -3404,7 +3471,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "select user.id, trim(leading 'x' from user.name) from user", @@ -3426,7 +3494,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "json utility functions", @@ -3448,7 +3517,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "dual query with exists clause", @@ -3546,7 +3616,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "yeah, it does not make sense, but it's valid", @@ -3639,7 +3710,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "groupe by with non aggregated columns and table alias", @@ -3661,7 +3733,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Functions that return JSON value attributes", @@ -3866,7 +3939,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "gtid functions", @@ -3934,7 +4008,8 @@ "user.user_extra", "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "Join across multiple tables, with conditions on different vindexes, but mergeable through join predicates", @@ -3962,7 +4037,8 @@ "user.music_extra", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "SQL_CALC_FOUND_ROWS with vindex lookup", @@ -4073,7 +4149,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "`None` route being merged with another route via join predicate on Vindex columns", @@ -4122,7 +4199,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Subquery with `IN` condition using columns with matching lookup vindexes", @@ -4200,7 +4278,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Subquery with `IN` condition using columns with matching lookup vindexes", @@ -4314,7 +4393,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Mergeable scatter subquery with `GROUP BY` on unique vindex column", @@ -4336,7 +4416,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Unmergeable scatter subquery with `GROUP BY` on-non vindex column", @@ -4375,26 +4456,52 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Unmergeable scatter subquery with LIMIT", @@ -4430,26 +4537,52 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Mergeable subquery with `MAX` aggregate and grouped by unique vindex", @@ -4483,26 +4616,52 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Unmergeable subquery with `MAX` aggregate", @@ -4543,19 +4702,44 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, @@ -4596,19 +4780,44 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, @@ -4649,26 +4858,52 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Mergeable subquery with multiple levels of derived statements", @@ -4722,6 +4957,36 @@ ] } }, + { + "comment": "We are using last_insert_id with argument, so we need to fetch all results", + "query": "select last_insert_id(5) from user limit 12", + "plan": { + "QueryType": "SELECT", + "Original": "select last_insert_id(5) from user limit 12", + "Instructions": { + "OperatorType": "Limit", + "Count": "12", + "RequireCompleteInput": true, + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FetchLastInsertID": true, + "FieldQuery": "select last_insert_id(5) from `user` where 1 != 1", + "Query": "select last_insert_id(5) from `user` limit 12", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } + }, { "comment": "Unmergeable subquery with multiple levels of derived statements, using a multi value `IN` predicate", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5, 6) LIMIT 10) subquery_for_limit) subquery_for_limit)", @@ -4760,26 +5025,52 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Unmergeable subquery with multiple levels of derived statements", @@ -4815,26 +5106,52 @@ }, { "InputName": "Outer", - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "IN", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", - "Table": "music", "Values": [ "::__sq1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values and music.id in ::__vals", + "Table": "music" + } + ] } ] }, "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "`None` subquery as top level predicate - outer query changes from `Scatter` to `None` on merge", @@ -5033,7 +5350,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "select user.a, t.b from user join (select id, count(*) b, req from user_extra group by req, id) as t on user.id = t.id", @@ -5097,7 +5415,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "SELECT music.id FROM (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other JOIN music ON other.maxt = music.id", @@ -5220,7 +5539,8 @@ "main.dual", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "subquery having join table on clause, using column reference of outer select table", @@ -5269,7 +5589,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "ALL modifier on unsharded table works well", @@ -5292,7 +5613,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "allow last_insert_id with argument", @@ -5307,6 +5629,7 @@ "Name": "user", "Sharded": true }, + "FetchLastInsertID": true, "FieldQuery": "select last_insert_id(id) from `user` where 1 != 1", "Query": "select last_insert_id(id) from `user`", "Table": "`user`" @@ -5337,7 +5660,8 @@ "user.music_extra", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Query with non-plannable lookup vindex", @@ -5363,7 +5687,8 @@ "TablesUsed": [ "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "join query with lookup and join on different vindex column", @@ -5415,7 +5740,8 @@ "user.user", "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "pick email as vindex lookup", @@ -5425,7 +5751,7 @@ "Original": "select * from customer where email = 'a@mail.com'", "Instructions": { "OperatorType": "VindexLookup", - "Variant": "Equal", + "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true @@ -5510,7 +5836,8 @@ "TablesUsed": [ "user.customer" ] - } + }, + "skip_e2e": true }, { "comment": "email vindex is costly than phone vindex - but phone vindex is backfiling hence ignored", @@ -5520,7 +5847,7 @@ "Original": "select * from customer where email = 'a@mail.com' and phone = 123456", "Instructions": { "OperatorType": "VindexLookup", - "Variant": "Equal", + "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true @@ -5571,7 +5898,7 @@ "Original": "select * from customer where phone = 123456 and email = 'a@mail.com'", "Instructions": { "OperatorType": "VindexLookup", - "Variant": "Equal", + "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true @@ -5634,7 +5961,8 @@ "TablesUsed": [ "user.samecolvin" ] - } + }, + "skip_e2e": true }, { "comment": "column with qualifier is correctly used", @@ -5677,7 +6005,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Derived tables going to a single shard still need to expand derived table columns", @@ -5722,7 +6051,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "column name aliases in outer join queries", @@ -5777,7 +6107,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "Over clause works for unsharded tables", @@ -5799,7 +6130,8 @@ "TablesUsed": [ "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "join with derived table with alias and join condition - merge into route", diff --git a/go/vt/vtgate/planbuilder/testdata/set_cases.json b/go/vt/vtgate/planbuilder/testdata/set_cases.json index 58cb2fffa75..02c5603a03c 100644 --- a/go/vt/vtgate/planbuilder/testdata/set_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/set_cases.json @@ -605,5 +605,28 @@ ] } } + }, + { + "comment": "set last_insert_id with agrument to user defined variable", + "query": "set @foo = last_insert_id(1)", + "plan": { + "QueryType": "SET", + "Original": "set @foo = last_insert_id(1)", + "Instructions": { + "OperatorType": "Set", + "Ops": [ + { + "Type": "UserDefinedVariable", + "Name": "foo", + "Expr": "last_insert_id(1)" + } + ], + "Inputs": [ + { + "OperatorType": "SingleRow" + } + ] + } + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.json b/go/vt/vtgate/planbuilder/testdata/union_cases.json index 7feabb0a698..2927c1c6093 100644 --- a/go/vt/vtgate/planbuilder/testdata/union_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/union_cases.json @@ -447,34 +447,84 @@ "OperatorType": "Concatenate", "Inputs": [ { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select 1 from music where 1 != 1", - "Query": "select distinct 1 from music where id = 1", - "Table": "music", "Values": [ "1" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from music where 1 != 1", + "Query": "select distinct 1 from music where id = 1", + "Table": "music" + } + ] }, { - "OperatorType": "Route", + "OperatorType": "VindexLookup", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select 1 from music where 1 != 1", - "Query": "select distinct 1 from music where id = 2", - "Table": "music", "Values": [ "2" ], - "Vindex": "music_user_map" + "Vindex": "music_user_map", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1", + "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals", + "Table": "name_user_vdx", + "Values": [ + "::name" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "ByDestination", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from music where 1 != 1", + "Query": "select distinct 1 from music where id = 2", + "Table": "music" + } + ] } ] } diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index 9241cec595c..55329586b0e 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -342,7 +342,12 @@ { "comment": "reference table delete with join", "query": "delete r from user u join ref_with_source r on u.col = r.col", - "plan": "VT12001: unsupported: DELETE on reference table with join" + "plan": "VT12001: unsupported: DML on reference table with join" + }, + { + "comment": "reference table update with join", + "query": "update user u join ref_with_source r on u.col = r.col set r.col = 5", + "plan": "VT12001: unsupported: DML on reference table with join" }, { "comment": "group_concat unsupported when needs full evaluation at vtgate with more than 1 column", diff --git a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json index 4fe275f2398..aaa11727510 100644 --- a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json +++ b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json @@ -58,34 +58,52 @@ "sharded": true, "vindexes": { "user_index": { - "type": "hash_test", + "type": "hash", "owner": "user" }, "kid_index": { - "type": "hash_test", + "type": "hash", "owner": "multicolvin" }, + "hash": { + "type": "hash" + }, "user_md5_index": { "type": "unicode_loose_md5" }, "music_user_map": { - "type": "lookup_test", - "owner": "music" + "type": "lookup_unique", + "owner": "music", + "params": { + "table": "name_user_vdx", + "from": "name", + "to": "keyspace_id" + } }, "cola_map": { - "type": "lookup_test", - "owner": "multicolvin" + "type": "lookup_unique", + "owner": "multicolvin", + "params": { + "table": "cola_map", + "from": "cola", + "to": "keyspace_id" + } }, "colb_colc_map": { - "type": "lookup_test", - "owner": "multicolvin" + "type": "lookup_unique", + "owner": "multicolvin", + "params": { + "table": "colb_colc_map", + "from": "colb,colc", + "to": "keyspace_id" + } }, "cola_kid_map": { - "type": "lookup_test", + "type": "lookup_unique", "owner": "overlap_vindex" }, "name_user_map": { - "type": "name_lkp_test", + "type": "lookup", "owner": "user", "params": { "table": "name_user_vdx", @@ -94,42 +112,56 @@ } }, "email_user_map": { - "type": "lookup_test", + "type": "lookup_unique", "owner": "user_metadata" }, "address_user_map": { - "type": "lookup_test", + "type": "lookup_unique", "owner": "user_metadata" }, "costly_map": { - "type": "costly", - "owner": "user" + "type": "lookup_cost", + "owner": "user", + "params": { + "table": "costly_map", + "from": "costly", + "to": "keyspace_id", + "cost": "100" + } }, "hash_dup": { - "type": "hash_test", + "type": "hash", "owner": "user" }, "vindex1": { - "type": "hash_test", + "type": "hash", "owner": "samecolvin" }, "vindex2": { - "type": "lookup_test", + "type": "lookup_unique", "owner": "samecolvin" }, "cfc": { "type": "cfc" }, "multicolIdx": { - "type": "multiCol_test" + "type": "multicol", + "params": { + "column_count": "2" + } }, "colc_map": { - "type": "lookup_test", + "type": "lookup_unique", "owner": "multicol_tbl" }, "name_muticoltbl_map": { - "type": "name_lkp_test", - "owner": "multicol_tbl" + "type": "lookup", + "owner": "multicol_tbl", + "params": { + "table": "name_user_vdx", + "from": "name", + "to": "keyspace_id" + } }, "non_planable_user_map": { "type": "lookup_unicodeloosemd5_hash", @@ -141,7 +173,7 @@ "owner": "user_metadata" }, "lkp_shard_map": { - "type": "name_lkp_test", + "type": "lookup_unique", "owner": "mixed_tbl", "params": { "table": "lkp_shard_vdx", @@ -153,18 +185,18 @@ "type": "xxhash" }, "unq_lkp_bf_vdx": { - "type": "unq_lkp_test", + "type": "lookup_unique", "owner": "customer", "params": { "table": "unq_lkp_idx", - "from": " ", + "from": "unq_key", "to": "keyspace_id", "cost": "100", "write_only": "true" } }, "unq_lkp_vdx": { - "type": "unq_lkp_test", + "type": "lookup_unique", "owner": "customer", "params": { "table": "unq_lkp_idx", @@ -174,14 +206,17 @@ } }, "lkp_bf_vdx": { - "type": "name_lkp_test", + "type": "lookup_unique", "owner": "customer", "params": { "table": "lkp_shard_vdx", - "from": " ", + "from": "unq_key", "to": "keyspace_id", "write_only": "true" } + }, + "binary": { + "type": "binary" } }, "tables": { @@ -352,6 +387,22 @@ } ] }, + "cola_map": { + "column_vindexes": [ + { + "column": "cola", + "name": "hash" + } + ] + }, + "colb_colc_map": { + "column_vindexes": [ + { + "column": "colb", + "name": "hash" + } + ] + }, "overlap_vindex": { "column_vindexes": [ { @@ -462,6 +513,14 @@ } ] }, + "costly_map": { + "column_vindexes": [ + { + "column": "name", + "name": "user_md5_index" + } + ] + }, "mixed_tbl": { "column_vindexes": [ { @@ -513,6 +572,62 @@ "name": "shard_index" } ] + }, + "unq_binary_idx": { + "column_vindexes" : [ + { + "column" : "id", + "name": "binary" + } + ], + "columns" :[ + { + "name": "col1", + "type": "INT16" + } + ] + }, + "sales": { + "column_vindexes" : [ + { + "column" : "oid", + "name" : "binary" + } + ], + "columns" : [ + { + "name" : "col1", + "type" : "VARCHAR" + } + ] + }, + "sales_extra" : { + "column_vindexes": [ + { + "columns": [ + "colx" + ], + "name": "shard_index" + } + ], + "columns" : [ + { + "name" : "cola", + "type" : "VARCHAR" + }, + { + "name" : "colb", + "type" : "VARCHAR" + }, + { + "name" : "start", + "type" : "INT16" + }, + { + "name" : "end", + "type" : "INT16" + } + ] } } }, @@ -641,7 +756,10 @@ "type": "hash_test" }, "multicolIdx": { - "type": "multiCol_test" + "type": "multicol", + "params": { + "column_count": "3" + } } }, "tables": { diff --git a/go/vt/vtgate/planbuilder/vexplain.go b/go/vt/vtgate/planbuilder/vexplain.go index 7aed1e48884..a12139c3068 100644 --- a/go/vt/vtgate/planbuilder/vexplain.go +++ b/go/vt/vtgate/planbuilder/vexplain.go @@ -55,7 +55,7 @@ func buildVExplainPlan( func explainTabPlan(explain *sqlparser.ExplainTab, vschema plancontext.VSchema) (*planResult, error) { var keyspace *vindexes.Keyspace - var destination key.Destination + var dest key.Destination if sqlparser.SystemSchema(explain.Table.Qualifier.String()) { var err error @@ -64,30 +64,26 @@ func explainTabPlan(explain *sqlparser.ExplainTab, vschema plancontext.VSchema) return nil, err } } else { + var tbl *vindexes.Table var err error - var ks string - _, _, ks, _, destination, err = vschema.FindTableOrVindex(explain.Table) + tbl, _, _, _, dest, err = vschema.FindTableOrVindex(explain.Table) if err != nil { return nil, err } - explain.Table.Qualifier = sqlparser.NewIdentifierCS("") - - keyspace, err = vschema.FindKeyspace(ks) - if err != nil { - return nil, err - } - if keyspace == nil { - return nil, vterrors.VT14004(ks) + if tbl == nil { + return nil, vterrors.VT05004(explain.Table.Name.String()) } + keyspace = tbl.Keyspace + explain.Table = sqlparser.NewTableName(tbl.Name.String()) } - if destination == nil { - destination = key.DestinationAnyShard{} + if dest == nil { + dest = key.DestinationAnyShard{} } return newPlanResult(&engine.Send{ Keyspace: keyspace, - TargetDestination: destination, + TargetDestination: dest, Query: sqlparser.String(explain), SingleShardOnly: true, }, singleTable(keyspace.Name, explain.Table.Name.String())), nil diff --git a/go/vt/vtgate/querylog.go b/go/vt/vtgate/querylog.go index bddc799363d..686ff419764 100644 --- a/go/vt/vtgate/querylog.go +++ b/go/vt/vtgate/querylog.go @@ -49,8 +49,8 @@ func (e *Executor) defaultQueryLogger() error { queryzHandler(e, w, r) }) - if queryLogToFile != "" { - _, err := queryLogger.LogToFile(queryLogToFile, streamlog.GetFormatter(queryLogger)) + if e.config.QueryLogToFile != "" { + _, err := queryLogger.LogToFile(e.config.QueryLogToFile, streamlog.GetFormatter(queryLogger)) if err != nil { return err } diff --git a/go/vt/vtgate/querylogz_test.go b/go/vt/vtgate/querylogz_test.go index 9236b2ac840..2bc5d7e2295 100644 --- a/go/vt/vtgate/querylogz_test.go +++ b/go/vt/vtgate/querylogz_test.go @@ -26,16 +26,17 @@ import ( "testing" "time" + "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/logstats" - "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/callerid" ) func TestQuerylogzHandlerFormatting(t *testing.T) { req, _ := http.NewRequest("GET", "/querylogz?timeout=10&limit=1", nil) - logStats := logstats.NewLogStats(context.Background(), "Execute", "select name, 'inject ' from test_table limit 1000", "suuid", nil) + logStats := logstats.NewLogStats(context.Background(), "Execute", + "select name, 'inject ' from test_table limit 1000", "suuid", nil, streamlog.NewQueryLogConfigForTest()) logStats.StmtType = "select" logStats.RowsAffected = 1000 logStats.ShardQueries = 1 @@ -139,8 +140,7 @@ func TestQuerylogzHandlerFormatting(t *testing.T) { checkQuerylogzHasStats(t, slowQueryPattern, logStats, body) // ensure querylogz is not affected by the filter tag - streamlog.SetQueryLogFilterTag("XXX_SKIP_ME") - defer func() { streamlog.SetQueryLogFilterTag("") }() + logStats.Config.FilterTag = "XXX_SKIP_ME" ch = make(chan *logstats.LogStats, 1) ch <- logStats querylogzHandler(ch, response, req, sqlparser.NewTestParser()) diff --git a/go/vt/vtgate/sandbox_test.go b/go/vt/vtgate/sandbox_test.go index fa5ffbbffd8..6030de2ba59 100644 --- a/go/vt/vtgate/sandbox_test.go +++ b/go/vt/vtgate/sandbox_test.go @@ -221,8 +221,12 @@ type sandboxTopo struct { // // when this version is used, WatchSrvVSchema can properly simulate watches func newSandboxForCells(ctx context.Context, cells []string) *sandboxTopo { + ts := memorytopo.NewServer(ctx, cells...) + for ks := range ksToSandbox { + ts.EnsureVSchema(ctx, ks) + } return &sandboxTopo{ - topoServer: memorytopo.NewServer(ctx, cells...), + ts, } } @@ -293,6 +297,16 @@ func (sct *sandboxTopo) WatchSrvVSchema(ctx context.Context, cell string, callba return } + // Update the backing topo server with the current sandbox vschemas. + for ks := range ksToSandbox { + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: ks, + Keyspace: srvVSchema.Keyspaces[ks], + } + if err := sct.topoServer.SaveVSchema(ctx, ksvs); err != nil { + panic(fmt.Sprintf("sandboxTopo SaveVSchema returned an error: %v", err)) + } + } sct.topoServer.UpdateSrvVSchema(ctx, cell, srvVSchema) current, updateChan, err := sct.topoServer.WatchSrvVSchema(ctx, cell) if err != nil { diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index 6e2cf9ad8ba..85f236a9a18 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -152,6 +152,7 @@ func (stc *ScatterConn) ExecuteMultiShard( autocommit bool, ignoreMaxMemoryRows bool, resultsObserver econtext.ResultsObserver, + fetchLastInsertID bool, ) (qr *sqltypes.Result, errs []error) { if len(rss) != len(queries) { @@ -166,6 +167,10 @@ func (stc *ScatterConn) ExecuteMultiShard( go stc.runLockQuery(ctx, session) } + if session.Options != nil { + session.Options.FetchLastInsertId = fetchLastInsertID + } + allErrors := stc.multiGoTransaction( ctx, "Execute", @@ -187,6 +192,10 @@ func (stc *ScatterConn) ExecuteMultiShard( opts = session.Session.Options } + if opts == nil && fetchLastInsertID { + opts = &querypb.ExecuteOptions{FetchLastInsertId: fetchLastInsertID} + } + if autocommit { // As this is auto-commit, the transactionID is supposed to be zero. if transactionID != int64(0) { @@ -373,6 +382,7 @@ func (stc *ScatterConn) StreamExecuteMulti( autocommit bool, callback func(reply *sqltypes.Result) error, resultsObserver econtext.ResultsObserver, + fetchLastInsertID bool, ) []error { if session.InLockSession() && triggerLockHeartBeat(session) { go stc.runLockQuery(ctx, session) @@ -384,6 +394,11 @@ func (stc *ScatterConn) StreamExecuteMulti( } return callback(reply) } + + if session.Options != nil { + session.Options.FetchLastInsertId = fetchLastInsertID + } + allErrors := stc.multiGoTransaction( ctx, "StreamExecute", @@ -404,6 +419,10 @@ func (stc *ScatterConn) StreamExecuteMulti( opts = session.Session.Options } + if opts == nil && fetchLastInsertID { + opts = &querypb.ExecuteOptions{FetchLastInsertId: fetchLastInsertID} + } + if autocommit { // As this is auto-commit, the transactionID is supposed to be zero. if transactionID != int64(0) { @@ -666,7 +685,7 @@ func (stc *ScatterConn) multiGoTransaction( startTime, statsKey := stc.startAction(name, rs.Target) defer stc.endAction(startTime, allErrors, statsKey, &err, session) - info, shardSession, err := actionInfo(ctx, rs.Target, session, autocommit, stc.txConn.mode) + info, shardSession, err := actionInfo(ctx, rs.Target, session, autocommit, stc.txConn.txMode.TransactionMode()) if err != nil { return } @@ -683,7 +702,7 @@ func (stc *ScatterConn) multiGoTransaction( shardSession.RowsAffected = info.rowsAffected } if info.actionNeeded != nothing && (info.transactionID != 0 || info.reservedID != 0) { - appendErr := session.AppendOrUpdate(rs.Target, info, shardSession, stc.txConn.mode) + appendErr := session.AppendOrUpdate(rs.Target, info, shardSession, stc.txConn.txMode.TransactionMode()) if appendErr != nil { err = appendErr } diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index ab8680ca5e6..e5c27c0de33 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -20,27 +20,23 @@ import ( "fmt" "testing" - "vitess.io/vitess/go/vt/log" - econtext "vitess.io/vitess/go/vt/vtgate/executorcontext" - - "vitess.io/vitess/go/mysql/sqlerror" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - + "github.com/aws/smithy-go/ptr" "github.com/stretchr/testify/assert" - - "vitess.io/vitess/go/vt/key" - - "vitess.io/vitess/go/test/utils" - "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/discovery" + "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/vterrors" + econtext "vitess.io/vitess/go/vt/vtgate/executorcontext" ) // This file uses the sandbox_test framework. @@ -101,7 +97,7 @@ func TestExecuteFailOnAutocommit(t *testing.T) { }, Autocommit: false, } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}, false) err := vterrors.Aggregate(errs) require.Error(t, err) require.Contains(t, err.Error(), "in autocommit mode, transactionID should be zero but was: 123") @@ -109,6 +105,117 @@ func TestExecuteFailOnAutocommit(t *testing.T) { utils.MustMatch(t, []*querypb.BoundQuery{queries[1]}, sbc1.Queries, "") } +func TestFetchLastInsertIDResets(t *testing.T) { + // This test verifies that the FetchLastInsertID flag is reset after a call to ExecuteMultiShard. + ks := "TestFetchLastInsertIDResets" + ctx := utils.LeakCheckContext(t) + + createSandbox(ks) + hc := discovery.NewFakeHealthCheck(nil) + sc := newTestScatterConn(ctx, hc, newSandboxForCells(ctx, []string{"aa"}), "aa") + sbc0 := hc.AddTestTablet("aa", "0", 1, ks, "0", topodatapb.TabletType_PRIMARY, true, 1, nil) + sbc1 := hc.AddTestTablet("aa", "1", 1, ks, "1", topodatapb.TabletType_PRIMARY, true, 1, nil) + + rss := []*srvtopo.ResolvedShard{{ + Target: &querypb.Target{ + Keyspace: ks, + Shard: "0", + TabletType: topodatapb.TabletType_PRIMARY, + }, + Gateway: sbc0, + }, { + Target: &querypb.Target{ + Keyspace: ks, + Shard: "1", + TabletType: topodatapb.TabletType_PRIMARY, + }, + Gateway: sbc1, + }} + queries := []*querypb.BoundQuery{{ + Sql: "query1", + BindVariables: map[string]*querypb.BindVariable{ + "bv0": sqltypes.Int64BindVariable(0), + }, + }, { + Sql: "query2", + BindVariables: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }} + tests := []struct { + name string + initialSessionOpts *querypb.ExecuteOptions + fetchLastInsertID bool + expectSessionNil bool + expectFetchLastID *bool // nil means checkLastOptionNil, otherwise checkLastOption(*bool) + }{ + { + name: "no session options, fetchLastInsertID = false", + initialSessionOpts: nil, + fetchLastInsertID: false, + expectSessionNil: true, + expectFetchLastID: nil, + }, + { + name: "no session options, fetchLastInsertID = true", + initialSessionOpts: nil, + fetchLastInsertID: true, + expectSessionNil: true, + + expectFetchLastID: ptr.Bool(true), + }, + { + name: "session options set, fetchLastInsertID = false", + initialSessionOpts: &querypb.ExecuteOptions{}, + fetchLastInsertID: false, + expectSessionNil: false, + expectFetchLastID: ptr.Bool(false), + }, + { + name: "session options set, fetchLastInsertID = true", + initialSessionOpts: &querypb.ExecuteOptions{}, + fetchLastInsertID: true, + expectSessionNil: false, + expectFetchLastID: ptr.Bool(true), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + session := econtext.NewSafeSession(nil) + session.Options = tt.initialSessionOpts + + checkLastOption := func(expected bool) { + require.Equal(t, 1, len(sbc0.Options)) + options := sbc0.Options[0] + assert.Equal(t, options.FetchLastInsertId, expected) + sbc0.Options = nil + } + checkLastOptionNil := func() { + require.Equal(t, 1, len(sbc0.Options)) + assert.Nil(t, sbc0.Options[0]) + sbc0.Options = nil + } + + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, true /*autocommit*/, false, nullResultsObserver{}, tt.fetchLastInsertID) + require.NoError(t, vterrors.Aggregate(errs)) + + if tt.expectSessionNil { + assert.Nil(t, session.Options) + } else { + assert.NotNil(t, session.Options) + assert.Equal(t, tt.fetchLastInsertID, session.Options.FetchLastInsertId) + } + + if tt.expectFetchLastID == nil { + checkLastOptionNil() + } else { + checkLastOption(*tt.expectFetchLastID) + } + }) + } +} + func TestExecutePanic(t *testing.T) { ctx := utils.LeakCheckContext(t) @@ -177,15 +284,10 @@ func TestExecutePanic(t *testing.T) { logMessage = fmt.Sprintf(format, args...) } - defer func() { - r := recover() - require.NotNil(t, r, "The code did not panic") - // assert we are seeing the stack trace - require.Contains(t, logMessage, "(*ScatterConn).multiGoTransaction") - }() - - _, _ = sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}) - + assert.Panics(t, func() { + _, _ = sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}, false) + }) + require.Contains(t, logMessage, "(*ScatterConn).multiGoTransaction") } func TestReservedOnMultiReplica(t *testing.T) { diff --git a/go/vt/vtgate/schema/tracker.go b/go/vt/vtgate/schema/tracker.go index a1b2009d0e1..8fa41712223 100644 --- a/go/vt/vtgate/schema/tracker.go +++ b/go/vt/vtgate/schema/tracker.go @@ -73,7 +73,7 @@ func NewTracker(ch chan *discovery.TabletHealth, enableViews, enableUDFs bool, p } if enableViews { - t.views = &viewMap{m: map[keyspaceStr]map[viewNameStr]sqlparser.SelectStatement{}, parser: parser} + t.views = &viewMap{m: map[keyspaceStr]map[viewNameStr]sqlparser.TableStatement{}, parser: parser} } if enableUDFs { t.udfs = map[keyspaceStr][]string{} @@ -283,7 +283,7 @@ func (t *Tracker) Tables(ks string) map[string]*vindexes.TableInfo { } // Views returns all known views in the keyspace with their definition. -func (t *Tracker) Views(ks string) map[string]sqlparser.SelectStatement { +func (t *Tracker) Views(ks string) map[string]sqlparser.TableStatement { if t.views == nil { return nil } @@ -525,14 +525,14 @@ func (t *Tracker) clearKeyspaceTables(ks string) { } type viewMap struct { - m map[keyspaceStr]map[viewNameStr]sqlparser.SelectStatement + m map[keyspaceStr]map[viewNameStr]sqlparser.TableStatement parser *sqlparser.Parser } func (vm *viewMap) set(ks, tbl, sql string) { m := vm.m[ks] if m == nil { - m = make(map[tableNameStr]sqlparser.SelectStatement) + m = make(map[tableNameStr]sqlparser.TableStatement) vm.m[ks] = m } stmt, err := vm.parser.Parse(sql) @@ -548,7 +548,7 @@ func (vm *viewMap) set(ks, tbl, sql string) { m[tbl] = cv.Select } -func (vm *viewMap) get(ks, tbl string) sqlparser.SelectStatement { +func (vm *viewMap) get(ks, tbl string) sqlparser.TableStatement { m := vm.m[ks] if m == nil { return nil @@ -571,7 +571,7 @@ func (t *Tracker) clearKeyspaceViews(ks string) { } // GetViews returns the view statement for the given keyspace and view name. -func (t *Tracker) GetViews(ks string, tbl string) sqlparser.SelectStatement { +func (t *Tracker) GetViews(ks string, tbl string) sqlparser.TableStatement { t.mu.Lock() defer t.mu.Unlock() diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index 0a9d2480d9b..c4e7dc55866 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -151,7 +151,7 @@ func (a *analyzer) newSemTable( ExpandedColumns: map[sqlparser.TableName][]*sqlparser.ColName{}, columns: map[*sqlparser.Union]sqlparser.SelectExprs{}, StatementIDs: a.scoper.statementIDs, - QuerySignature: QuerySignature{}, + QuerySignature: a.sig, childForeignKeysInvolved: map[TableSet][]vindexes.ChildFKInfo{}, parentForeignKeysInvolved: map[TableSet][]vindexes.ParentFKInfo{}, childFkToUpdExprs: map[string]sqlparser.UpdateExprs{}, @@ -174,7 +174,7 @@ func (a *analyzer) newSemTable( Direct: a.binder.direct, ExprTypes: a.typer.m, Tables: a.tables.Tables, - Targets: a.binder.targets, + DMLTargets: a.binder.targets, NotSingleRouteErr: a.notSingleRouteErr, NotUnshardedErr: a.unshardedErr, Warning: a.warning, @@ -286,14 +286,22 @@ func containsStar(s sqlparser.SelectExprs) bool { } func checkUnionColumns(union *sqlparser.Union) error { - firstProj := sqlparser.GetFirstSelect(union).SelectExprs + lft, err := sqlparser.GetFirstSelect(union) + if err != nil { + return err + } + firstProj := lft.GetColumns() if containsStar(firstProj) { // if we still have *, we can't figure out if the query is invalid or not // we'll fail it at run time instead return nil } - secondProj := sqlparser.GetFirstSelect(union.Right).SelectExprs + rgt, err := sqlparser.GetFirstSelect(union.Right) + if err != nil { + return err + } + secondProj := rgt.GetColumns() if containsStar(secondProj) { return nil } @@ -362,6 +370,10 @@ func (a *analyzer) analyze(statement sqlparser.Statement) error { return a.err } + if a.earlyTables.lastInsertIdWithArgument { + a.sig.LastInsertIDArg = true + } + if a.canShortCut(statement) { return nil } diff --git a/go/vt/vtgate/semantics/analyzer_test.go b/go/vt/vtgate/semantics/analyzer_test.go index 0c42456b0ab..3f7a21cb6ac 100644 --- a/go/vt/vtgate/semantics/analyzer_test.go +++ b/go/vt/vtgate/semantics/analyzer_test.go @@ -625,6 +625,36 @@ func TestSubqueryOrderByBinding(t *testing.T) { } } +func TestQuerySignatureLastInsertID(t *testing.T) { + queries := []struct { + query string + expected bool + }{{ + query: "select 12", + expected: false, + }, { + query: "select last_insert_id()", + expected: false, + }, { + query: "select last_insert_id(123)", + expected: true, + }, { + query: "update user_extra set val = last_insert_id(123)", + expected: true, + }} + + for _, tc := range queries { + t.Run(tc.query, func(t *testing.T) { + ast, err := sqlparser.NewTestParser().Parse(tc.query) + require.NoError(t, err) + + st, err := AnalyzeStrict(ast, "dbName", fakeSchemaInfo()) + require.NoError(t, err) + require.Equal(t, tc.expected, st.QuerySignature.LastInsertIDArg) + }) + } +} + func TestOrderByBindingTable(t *testing.T) { tcases := []struct { sql string @@ -973,8 +1003,10 @@ func TestUnionWithOrderBy(t *testing.T) { stmt, semTable := parseAndAnalyze(t, query, "") union, _ := stmt.(*sqlparser.Union) - sel1 := sqlparser.GetFirstSelect(union) - sel2 := sqlparser.GetFirstSelect(union.Right) + sel1, err := sqlparser.GetFirstSelect(union) + require.NoError(t, err) + sel2, err := sqlparser.GetFirstSelect(union.Right) + require.NoError(t, err) t1 := sel1.From[0].(*sqlparser.AliasedTableExpr) t2 := sel2.From[0].(*sqlparser.AliasedTableExpr) diff --git a/go/vt/vtgate/semantics/cte_table.go b/go/vt/vtgate/semantics/cte_table.go index 498fc5076c1..7083fea10d2 100644 --- a/go/vt/vtgate/semantics/cte_table.go +++ b/go/vt/vtgate/semantics/cte_table.go @@ -150,7 +150,7 @@ func (cte *CTETable) GetMirrorRule() *vindexes.MirrorRule { type CTE struct { Name string - Query sqlparser.SelectStatement + Query sqlparser.TableStatement isAuthoritative bool recursiveDeps *TableSet Columns sqlparser.Columns diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go index 3e53ed0816a..64426e25748 100644 --- a/go/vt/vtgate/semantics/early_rewriter.go +++ b/go/vt/vtgate/semantics/early_rewriter.go @@ -385,12 +385,16 @@ func getIntLiteral(e sqlparser.Expr) *sqlparser.Literal { // handleOrderBy processes the ORDER BY clause. func (r *earlyRewriter) handleOrderBy(parent sqlparser.SQLNode, iter iterator) error { - stmt, ok := parent.(sqlparser.SelectStatement) + stmt, ok := parent.(sqlparser.TableStatement) if !ok { return nil } - sel := sqlparser.GetFirstSelect(stmt) + sel, err := sqlparser.GetFirstSelect(stmt) + if err != nil { + return err + } + for e := iter.next(); e != nil; e = iter.next() { lit, err := r.replaceLiteralsInOrderBy(e, iter) if err != nil { @@ -419,12 +423,15 @@ func (r *earlyRewriter) handleOrderBy(parent sqlparser.SQLNode, iter iterator) e // handleGroupBy processes the GROUP BY clause. func (r *earlyRewriter) handleGroupBy(parent sqlparser.SQLNode, iter iterator) error { - stmt, ok := parent.(sqlparser.SelectStatement) + stmt, ok := parent.(*sqlparser.Select) if !ok { return nil } - sel := sqlparser.GetFirstSelect(stmt) + sel, err := sqlparser.GetFirstSelect(stmt) + if err != nil { + return err + } for e := iter.next(); e != nil; e = iter.next() { expr, err := r.replaceLiteralsInGroupBy(e) if err != nil { @@ -435,7 +442,6 @@ func (r *earlyRewriter) handleGroupBy(parent sqlparser.SQLNode, iter iterator) e if err != nil { return err } - } err = iter.replace(expr) if err != nil { diff --git a/go/vt/vtgate/semantics/info_schema.go b/go/vt/vtgate/semantics/info_schema.go index 127f4a00960..b33a20620e4 100644 --- a/go/vt/vtgate/semantics/info_schema.go +++ b/go/vt/vtgate/semantics/info_schema.go @@ -699,7 +699,7 @@ func getInfoSchema57() map[string][]vindexes.Column { // getInfoSchema80 returns a map of all information_schema tables and their columns with types // To recreate this information from MySQL, you can run the test in info_schema_gen_test.go func getInfoSchema80() map[string][]vindexes.Column { - parser, err := sqlparser.New(sqlparser.Options{MySQLServerVersion: "8.0.30"}) + parser, err := sqlparser.New(sqlparser.Options{MySQLServerVersion: "8.0.40"}) if err != nil { panic(err) } diff --git a/go/vt/vtgate/semantics/scoper.go b/go/vt/vtgate/semantics/scoper.go index 9d596d9ecd1..e6df3c3a5b0 100644 --- a/go/vt/vtgate/semantics/scoper.go +++ b/go/vt/vtgate/semantics/scoper.go @@ -297,11 +297,11 @@ func (s *scoper) createSpecialScopePostProjection(parent sqlparser.SQLNode) erro for i, sel := range sqlparser.GetAllSelects(parent) { if i == 0 { nScope.stmt = sel - tableInfo = createVTableInfoForExpressions(sel.SelectExprs, nil /*needed for star expressions*/, s.org) + tableInfo = createVTableInfoForExpressions(sel.GetColumns(), nil /*needed for star expressions*/, s.org) nScope.tables = append(nScope.tables, tableInfo) continue } - thisTableInfo := createVTableInfoForExpressions(sel.SelectExprs, nil /*needed for star expressions*/, s.org) + thisTableInfo := createVTableInfoForExpressions(sel.GetColumns(), nil /*needed for star expressions*/, s.org) if len(tableInfo.cols) != len(thisTableInfo.cols) { return vterrors.NewErrorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.WrongNumberOfColumnsInSelect, "The used SELECT statements have a different number of columns") } diff --git a/go/vt/vtgate/semantics/semantic_table.go b/go/vt/vtgate/semantics/semantic_table.go index f9856a901a6..e3eead71c90 100644 --- a/go/vt/vtgate/semantics/semantic_table.go +++ b/go/vt/vtgate/semantics/semantic_table.go @@ -80,13 +80,14 @@ type ( // QuerySignature is used to identify shortcuts in the planning process QuerySignature struct { - Aggregation bool - DML bool - Distinct bool - HashJoin bool - SubQueries bool - Union bool - RecursiveCTE bool + Aggregation bool + DML bool + Distinct bool + HashJoin bool + SubQueries bool + Union bool + RecursiveCTE bool + LastInsertIDArg bool // LastInsertIDArg is true if the query has a LAST_INSERT_ID(x) with an argument } // MirrorInfo stores information used to produce mirror @@ -129,8 +130,8 @@ type ( // It doesn't recurse inside derived tables to find the original dependencies. Direct ExprDependencies - // Targets contains the TableSet of each table getting modified by the update/delete statement. - Targets TableSet + // DMLTargets contains the TableSet of each table getting modified by the update/delete statement. + DMLTargets TableSet // ColumnEqualities is used for transitive closures (e.g., if a == b and b == c, then a == c). ColumnEqualities map[columnName][]sqlparser.Expr @@ -202,7 +203,7 @@ func (st *SemTable) CopyDependencies(from, to sqlparser.Expr) { // GetChildForeignKeysForTargets gets the child foreign keys as a list for all the target tables. func (st *SemTable) GetChildForeignKeysForTargets() (fks []vindexes.ChildFKInfo) { - for _, ts := range st.Targets.Constituents() { + for _, ts := range st.DMLTargets.Constituents() { fks = append(fks, st.childForeignKeysInvolved[ts]...) } return fks @@ -210,7 +211,7 @@ func (st *SemTable) GetChildForeignKeysForTargets() (fks []vindexes.ChildFKInfo) // GetChildForeignKeysForTableSet gets the child foreign keys as a listfor the TableSet. func (st *SemTable) GetChildForeignKeysForTableSet(target TableSet) (fks []vindexes.ChildFKInfo) { - for _, ts := range st.Targets.Constituents() { + for _, ts := range st.DMLTargets.Constituents() { if target.IsSolvedBy(ts) { fks = append(fks, st.childForeignKeysInvolved[ts]...) } @@ -238,7 +239,7 @@ func (st *SemTable) GetChildForeignKeysList() []vindexes.ChildFKInfo { // GetParentForeignKeysForTargets gets the parent foreign keys as a list for all the target tables. func (st *SemTable) GetParentForeignKeysForTargets() (fks []vindexes.ParentFKInfo) { - for _, ts := range st.Targets.Constituents() { + for _, ts := range st.DMLTargets.Constituents() { fks = append(fks, st.parentForeignKeysInvolved[ts]...) } return fks @@ -246,7 +247,7 @@ func (st *SemTable) GetParentForeignKeysForTargets() (fks []vindexes.ParentFKInf // GetParentForeignKeysForTableSet gets the parent foreign keys as a list for the TableSet. func (st *SemTable) GetParentForeignKeysForTableSet(target TableSet) (fks []vindexes.ParentFKInfo) { - for _, ts := range st.Targets.Constituents() { + for _, ts := range st.DMLTargets.Constituents() { if target.IsSolvedBy(ts) { fks = append(fks, st.parentForeignKeysInvolved[ts]...) } @@ -492,7 +493,7 @@ func (st *SemTable) ForeignKeysPresent() bool { return false } -func (st *SemTable) SelectExprs(sel sqlparser.SelectStatement) sqlparser.SelectExprs { +func (st *SemTable) SelectExprs(sel sqlparser.TableStatement) sqlparser.SelectExprs { switch sel := sel.(type) { case *sqlparser.Select: return sel.SelectExprs @@ -970,7 +971,7 @@ func (st *SemTable) UpdateChildFKExpr(origUpdExpr *sqlparser.UpdateExpr, newExpr // GetTargetTableSetForTableName returns the TableSet for the given table name from the target tables. func (st *SemTable) GetTargetTableSetForTableName(name sqlparser.TableName) (TableSet, error) { - for _, target := range st.Targets.Constituents() { + for _, target := range st.DMLTargets.Constituents() { tbl, err := st.Tables[target.TableOffset()].Name() if err != nil { return "", err @@ -1013,6 +1014,13 @@ func (st *SemTable) GetMirrorInfo() MirrorInfo { return mirrorInfo(st.Tables) } +func (st *SemTable) ShouldFetchLastInsertID() bool { + if st == nil { + return false + } + return st.QuerySignature.LastInsertIDArg +} + // mirrorInfo looks through all tables with mirror rules defined, and returns a // MirrorInfo containing the lowest mirror percentage found across all rules. // diff --git a/go/vt/vtgate/semantics/table_collector.go b/go/vt/vtgate/semantics/table_collector.go index 191d9c3b38e..329ebcef254 100644 --- a/go/vt/vtgate/semantics/table_collector.go +++ b/go/vt/vtgate/semantics/table_collector.go @@ -46,6 +46,10 @@ type ( // cte is a map of CTE definitions that are used in the query cte map[string]*CTE + + // lastInsertIdWithArgument is used to signal to later stages that we + // need to do special handling of the engine primitive + lastInsertIdWithArgument bool } ) @@ -59,18 +63,22 @@ func newEarlyTableCollector(si SchemaInformation, currentDb string) *earlyTableC } func (etc *earlyTableCollector) down(cursor *sqlparser.Cursor) bool { - with, ok := cursor.Node().(*sqlparser.With) - if !ok { - return true - } - for _, cte := range with.CTEs { - etc.cte[cte.ID.String()] = &CTE{ - Name: cte.ID.String(), - Query: cte.Subquery, - Columns: cte.Columns, - Recursive: with.Recursive, + switch node := cursor.Node().(type) { + case *sqlparser.With: + for _, cte := range node.CTEs { + etc.cte[cte.ID.String()] = &CTE{ + Name: cte.ID.String(), + Query: cte.Subquery, + Columns: cte.Columns, + Recursive: node.Recursive, + } + } + case *sqlparser.FuncExpr: + if node.Name.EqualString("last_insert_id") && len(node.Exprs) == 1 { + etc.lastInsertIdWithArgument = true } } + return true } @@ -146,8 +154,11 @@ func (tc *tableCollector) visitAliasedTableExpr(node *sqlparser.AliasedTableExpr } func (tc *tableCollector) visitUnion(union *sqlparser.Union) error { - firstSelect := sqlparser.GetFirstSelect(union) - expanded, selectExprs := getColumnNames(firstSelect.SelectExprs) + firstSelect, err := sqlparser.GetFirstSelect(union) + if err != nil { + return err + } + expanded, selectExprs := getColumnNames(firstSelect.GetColumns()) info := unionInfo{ isAuthoritative: expanded, exprs: selectExprs, @@ -157,12 +168,12 @@ func (tc *tableCollector) visitUnion(union *sqlparser.Union) error { return nil } - size := len(firstSelect.SelectExprs) + size := firstSelect.GetColumnCount() info.recursive = make([]TableSet, size) typers := make([]evalengine.TypeAggregator, size) collations := tc.org.collationEnv() - err := sqlparser.VisitAllSelects(union, func(s *sqlparser.Select, idx int) error { + err = sqlparser.VisitAllSelects(union, func(s *sqlparser.Select, idx int) error { for i, expr := range s.SelectExprs { ae, ok := expr.(*sqlparser.AliasedExpr) if !ok { @@ -405,7 +416,10 @@ func checkValidRecursiveCTE(cteDef *CTE) error { return vterrors.VT09026(cteDef.Name) } - firstSelect := sqlparser.GetFirstSelect(union.Right) + firstSelect, err := sqlparser.GetFirstSelect(union.Right) + if err != nil { + return err + } if firstSelect.GroupBy != nil { return vterrors.VT09027(cteDef.Name) } @@ -462,8 +476,16 @@ func (tc *tableCollector) addSelectDerivedTable( return scope.addTable(tableInfo) } -func (tc *tableCollector) addUnionDerivedTable(union *sqlparser.Union, node *sqlparser.AliasedTableExpr, columns sqlparser.Columns, alias sqlparser.IdentifierCS) error { - firstSelect := sqlparser.GetFirstSelect(union) +func (tc *tableCollector) addUnionDerivedTable( + union *sqlparser.Union, + node *sqlparser.AliasedTableExpr, + columns sqlparser.Columns, + alias sqlparser.IdentifierCS, +) error { + firstSelect, err := sqlparser.GetFirstSelect(union) + if err != nil { + return err + } tables := tc.scoper.wScope[firstSelect] info, found := tc.unionInfo[union] if !found { diff --git a/go/vt/vtgate/simplifier/simplifier.go b/go/vt/vtgate/simplifier/simplifier.go index e838450e3a2..c15e2ea58d1 100644 --- a/go/vt/vtgate/simplifier/simplifier.go +++ b/go/vt/vtgate/simplifier/simplifier.go @@ -25,17 +25,17 @@ import ( // SimplifyStatement simplifies the AST of a query. It basically iteratively prunes leaves of the AST, as long as the pruning // continues to return true from the `test` function. func SimplifyStatement( - in sqlparser.SelectStatement, + in sqlparser.TableStatement, currentDB string, si semantics.SchemaInformation, - testF func(sqlparser.SelectStatement) bool, -) sqlparser.SelectStatement { + testF func(sqlparser.TableStatement) bool, +) sqlparser.TableStatement { tables, err := getTables(in, currentDB, si) if err != nil { panic(err) } - test := func(s sqlparser.SelectStatement) bool { + test := func(s sqlparser.TableStatement) bool { // Since our semantic analysis changes the AST, we clone it first, so we have a pristine AST to play with return testF(sqlparser.Clone(s)) } @@ -68,7 +68,7 @@ func SimplifyStatement( return in } -func trySimplifyDistinct(in sqlparser.SelectStatement, test func(statement sqlparser.SelectStatement) bool) sqlparser.SelectStatement { +func trySimplifyDistinct(in sqlparser.TableStatement, test func(statement sqlparser.TableStatement) bool) sqlparser.TableStatement { simplified := false alwaysVisitChildren := func(node, parent sqlparser.SQLNode) bool { return true @@ -100,7 +100,7 @@ func trySimplifyDistinct(in sqlparser.SelectStatement, test func(statement sqlpa return nil } -func trySimplifyExpressions(in sqlparser.SelectStatement, test func(sqlparser.SelectStatement) bool) sqlparser.SelectStatement { +func trySimplifyExpressions(in sqlparser.TableStatement, test func(sqlparser.TableStatement) bool) sqlparser.TableStatement { simplified := false visit := func(cursor expressionCursor) bool { // first - let's try to remove the expression @@ -141,7 +141,7 @@ func trySimplifyExpressions(in sqlparser.SelectStatement, test func(sqlparser.Se return nil } -func trySimplifyUnions(in sqlparser.SelectStatement, test func(sqlparser.SelectStatement) bool) (res sqlparser.SelectStatement) { +func trySimplifyUnions(in sqlparser.TableStatement, test func(subquery sqlparser.TableStatement) bool) (res sqlparser.TableStatement) { if union, ok := in.(*sqlparser.Union); ok { // the root object is an UNION if test(sqlparser.Clone(union.Left)) { @@ -193,7 +193,7 @@ func trySimplifyUnions(in sqlparser.SelectStatement, test func(sqlparser.SelectS return nil } -func tryRemoveTable(tables []semantics.TableInfo, in sqlparser.SelectStatement, currentDB string, si semantics.SchemaInformation, test func(sqlparser.SelectStatement) bool) sqlparser.SelectStatement { +func tryRemoveTable(tables []semantics.TableInfo, in sqlparser.TableStatement, currentDB string, si semantics.SchemaInformation, test func(sqlparser.TableStatement) bool) sqlparser.TableStatement { // 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.Clone(in) @@ -209,7 +209,7 @@ func tryRemoveTable(tables []semantics.TableInfo, in sqlparser.SelectStatement, return nil } -func getTables(in sqlparser.SelectStatement, currentDB string, si semantics.SchemaInformation) ([]semantics.TableInfo, error) { +func getTables(in sqlparser.TableStatement, 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.Clone(in) semTable, err := semantics.Analyze(clone, currentDB, si) @@ -219,7 +219,7 @@ func getTables(in sqlparser.SelectStatement, currentDB string, si semantics.Sche return semTable.Tables, nil } -func simplifyStarExpr(in sqlparser.SelectStatement, test func(sqlparser.SelectStatement) bool) sqlparser.SelectStatement { +func simplifyStarExpr(in sqlparser.TableStatement, test func(sqlparser.TableStatement) bool) sqlparser.TableStatement { simplified := false alwaysVisitChildren := func(node, parent sqlparser.SQLNode) bool { return true @@ -254,7 +254,7 @@ func simplifyStarExpr(in sqlparser.SelectStatement, test func(sqlparser.SelectSt // removeTable removes the table with the given index from the select statement, which includes the FROM clause // but also all expressions and predicates that depend on the table -func removeTable(clone sqlparser.SelectStatement, searchedTS semantics.TableSet, db string, si semantics.SchemaInformation) bool { +func removeTable(clone sqlparser.TableStatement, searchedTS semantics.TableSet, db string, si semantics.SchemaInformation) bool { semTable, err := semantics.Analyze(clone, db, si) if err != nil { panic(err) @@ -429,7 +429,7 @@ func newExprCursor(expr sqlparser.Expr, replace func(replaceWith sqlparser.Expr) // This cursor has a few extra capabilities that the normal sqlparser.SafeRewrite does not have, // such as visiting and being able to change individual expressions in a AND tree // if visit returns true, then traversal continues, otherwise traversal stops -func visitAllExpressionsInAST(clone sqlparser.SelectStatement, visit func(expressionCursor) bool) { +func visitAllExpressionsInAST(clone sqlparser.TableStatement, visit func(expressionCursor) bool) { alwaysVisitChildren := func(node, parent sqlparser.SQLNode) bool { return true } diff --git a/go/vt/vtgate/simplifier/simplifier_test.go b/go/vt/vtgate/simplifier/simplifier_test.go index 340497da8ef..0948f720f2d 100644 --- a/go/vt/vtgate/simplifier/simplifier_test.go +++ b/go/vt/vtgate/simplifier/simplifier_test.go @@ -52,7 +52,7 @@ limit 123 offset 456 ` ast, err := sqlparser.NewTestParser().Parse(query) require.NoError(t, err) - visitAllExpressionsInAST(ast.(sqlparser.SelectStatement), func(cursor expressionCursor) bool { + visitAllExpressionsInAST(ast.(sqlparser.TableStatement), func(cursor expressionCursor) bool { fmt.Printf(">> found expression: %s\n", sqlparser.String(cursor.expr)) cursor.remove() fmt.Printf("remove: %s\n", sqlparser.String(ast)) @@ -70,7 +70,7 @@ func TestAbortExpressionCursor(t *testing.T) { query := "select user.id, count(*), unsharded.name from user join unsharded on 13 = 14 where unsharded.id = 42 and name = 'foo' and user.id = unsharded.id" ast, err := sqlparser.NewTestParser().Parse(query) require.NoError(t, err) - visitAllExpressionsInAST(ast.(sqlparser.SelectStatement), func(cursor expressionCursor) bool { + visitAllExpressionsInAST(ast.(sqlparser.TableStatement), func(cursor expressionCursor) bool { fmt.Println(sqlparser.String(cursor.expr)) cursor.replace(sqlparser.NewIntLiteral("1")) fmt.Println(sqlparser.String(ast)) diff --git a/go/vt/vtgate/static_config.go b/go/vt/vtgate/static_config.go new file mode 100644 index 00000000000..f78545ebc5b --- /dev/null +++ b/go/vt/vtgate/static_config.go @@ -0,0 +1,40 @@ +/* +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 vtgate + +import vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + +// StaticConfig is a static configuration for vtgate. +// It is used for tests and vtexplain_vtgate where we don't want the user to +// control certain configs. +type StaticConfig struct { + OnlineDDLEnabled bool + DirectDDLEnabled bool + TxMode vtgatepb.TransactionMode +} + +func (s *StaticConfig) OnlineEnabled() bool { + return s.OnlineDDLEnabled +} + +func (s *StaticConfig) DirectEnabled() bool { + return s.DirectDDLEnabled +} + +func (s *StaticConfig) TransactionMode() vtgatepb.TransactionMode { + return s.TxMode +} diff --git a/go/vt/vtgate/tx_conn.go b/go/vt/vtgate/tx_conn.go index 3ce138bc0e4..dbd76b04c7a 100644 --- a/go/vt/vtgate/tx_conn.go +++ b/go/vt/vtgate/tx_conn.go @@ -33,6 +33,7 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/dynamicconfig" econtext "vitess.io/vitess/go/vt/vtgate/executorcontext" "vitess.io/vitess/go/vt/vttablet/queryservice" ) @@ -44,14 +45,14 @@ const nonAtomicCommitWarnMaxShards = 16 // TxConn is used for executing transactional requests. type TxConn struct { tabletGateway *TabletGateway - mode vtgatepb.TransactionMode + txMode dynamicconfig.TxMode } // NewTxConn builds a new TxConn. -func NewTxConn(gw *TabletGateway, txMode vtgatepb.TransactionMode) *TxConn { +func NewTxConn(gw *TabletGateway, txMode dynamicconfig.TxMode) *TxConn { return &TxConn{ tabletGateway: gw, - mode: txMode, + txMode: txMode, } } @@ -114,14 +115,38 @@ func (txc *TxConn) Commit(ctx context.Context, session *econtext.SafeSession) er case vtgatepb.TransactionMode_TWOPC: twopc = true case vtgatepb.TransactionMode_UNSPECIFIED: - twopc = txc.mode == vtgatepb.TransactionMode_TWOPC + twopc = txc.txMode.TransactionMode() == vtgatepb.TransactionMode_TWOPC } defer recordCommitTime(session, twopc, time.Now()) + + err := txc.runSessions(ctx, session.PreSessions, session.GetLogger(), txc.commitShard) + if err != nil { + _ = txc.Release(ctx, session) + return err + } + if twopc { - return txc.commit2PC(ctx, session) + err = txc.commit2PC(ctx, session) + } else { + err = txc.commitNormal(ctx, session) + } + + if err != nil { + _ = txc.Release(ctx, session) + return err } - return txc.commitNormal(ctx, session) + + err = txc.runSessions(ctx, session.PostSessions, session.GetLogger(), txc.commitShard) + if err != nil { + // If last commit fails, there will be nothing to rollback. + session.RecordWarning(&querypb.QueryWarning{Message: fmt.Sprintf("post-operation transaction had an error: %v", err)}) + // With reserved connection we should release them. + if session.InReservedConn() { + _ = txc.Release(ctx, session) + } + } + return nil } func recordCommitTime(session *econtext.SafeSession, twopc bool, startTime time.Time) { @@ -165,11 +190,6 @@ func (txc *TxConn) commitShard(ctx context.Context, s *vtgatepb.Session_ShardSes } func (txc *TxConn) commitNormal(ctx context.Context, session *econtext.SafeSession) error { - if err := txc.runSessions(ctx, session.PreSessions, session.GetLogger(), txc.commitShard); err != nil { - _ = txc.Release(ctx, session) - return err - } - // Retain backward compatibility on commit order for the normal session. for i, shardSession := range session.ShardSessions { if err := txc.commitShard(ctx, shardSession, session.GetLogger()); err != nil { @@ -193,19 +213,9 @@ func (txc *TxConn) commitNormal(ctx context.Context, session *econtext.SafeSessi }) warnings.Add("NonAtomicCommit", 1) } - _ = txc.Release(ctx, session) return err } } - - if err := txc.runSessions(ctx, session.PostSessions, session.GetLogger(), txc.commitShard); err != nil { - // If last commit fails, there will be nothing to rollback. - session.RecordWarning(&querypb.QueryWarning{Message: fmt.Sprintf("post-operation transaction had an error: %v", err)}) - // With reserved connection we should release them. - if session.InReservedConn() { - _ = txc.Release(ctx, session) - } - } return nil } @@ -216,11 +226,6 @@ func (txc *TxConn) commit2PC(ctx context.Context, session *econtext.SafeSession) return txc.commitNormal(ctx, session) } - if err := txc.checkValidCondition(session); err != nil { - _ = txc.Rollback(ctx, session) - return err - } - mmShard := session.ShardSessions[0] rmShards := session.ShardSessions[1:] dtid := dtids.New(mmShard) @@ -301,13 +306,6 @@ func (txc *TxConn) commit2PC(ctx context.Context, session *econtext.SafeSession) return nil } -func (txc *TxConn) checkValidCondition(session *econtext.SafeSession) error { - if len(session.PreSessions) != 0 || len(session.PostSessions) != 0 { - return vterrors.VT12001("atomic distributed transaction commit with consistent lookup vindex") - } - return nil -} - func (txc *TxConn) errActionAndLogWarn( ctx context.Context, session *econtext.SafeSession, diff --git a/go/vt/vtgate/tx_conn_test.go b/go/vt/vtgate/tx_conn_test.go index 333094569c8..6d31aa4e543 100644 --- a/go/vt/vtgate/tx_conn_test.go +++ b/go/vt/vtgate/tx_conn_test.go @@ -58,7 +58,7 @@ func TestTxConnBegin(t *testing.T) { require.NoError(t, err) wantSession := vtgatepb.Session{InTransaction: true} utils.MustMatch(t, &wantSession, session, "Session") - _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, safeSession, false, false, nullResultsObserver{}) + _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, safeSession, false, false, nullResultsObserver{}, false) require.Empty(t, errors) // Begin again should cause a commit and a new begin. @@ -72,13 +72,13 @@ func TestTxConnCommitFailure(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbcs, rssm, rssa := newTestTxConnEnvNShards(t, ctx, "TestTxConn", 3) - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} nonAtomicCommitCount := warnings.Counts()["NonAtomicCommit"] // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rssm[0], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[0], queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -93,7 +93,7 @@ func TestTxConnCommitFailure(t *testing.T) { } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rssm[1], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[1], queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -116,7 +116,7 @@ func TestTxConnCommitFailure(t *testing.T) { } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rssa, threeQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssa, threeQueries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -173,7 +173,7 @@ func TestTxConnCommitFailureAfterNonAtomicCommitMaxShards(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbcs, rssm, _ := newTestTxConnEnvNShards(t, ctx, "TestTxConn", 18) - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} nonAtomicCommitCount := warnings.Counts()["NonAtomicCommit"] // Sequence the executes to ensure commit order @@ -185,7 +185,7 @@ func TestTxConnCommitFailureAfterNonAtomicCommitMaxShards(t *testing.T) { } for i := 0; i < 18; i++ { - sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}, false) wantSession.ShardSessions = append(wantSession.ShardSessions, &vtgatepb.Session_ShardSession{ Target: &querypb.Target{ Keyspace: "TestTxConn", @@ -227,7 +227,7 @@ func TestTxConnCommitFailureBeforeNonAtomicCommitMaxShards(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbcs, rssm, _ := newTestTxConnEnvNShards(t, ctx, "TestTxConn", 17) - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} nonAtomicCommitCount := warnings.Counts()["NonAtomicCommit"] // Sequence the executes to ensure commit order @@ -239,7 +239,7 @@ func TestTxConnCommitFailureBeforeNonAtomicCommitMaxShards(t *testing.T) { } for i := 0; i < 17; i++ { - sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}, false) wantSession.ShardSessions = append(wantSession.ShardSessions, &vtgatepb.Session_ShardSession{ Target: &querypb.Target{ Keyspace: "TestTxConn", @@ -281,11 +281,11 @@ func TestTxConnCommitSuccess(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConn") - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -299,7 +299,7 @@ func TestTxConnCommitSuccess(t *testing.T) { }}, } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -334,11 +334,11 @@ func TestTxConnReservedCommitSuccess(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConn") - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -354,7 +354,7 @@ func TestTxConnReservedCommitSuccess(t *testing.T) { }}, } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -419,15 +419,15 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndCommit(t *testing.T) { keyspace := "TestTxConn" sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, keyspace) - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} // Sequence the executes to ensure shard session order session := econtext.NewSafeSession(&vtgatepb.Session{InReservedConn: true}) // this will create reserved connections against all tablets - _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) - _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) wantSession := vtgatepb.Session{ @@ -455,7 +455,7 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndCommit(t *testing.T) { session.Session.InTransaction = true // start a transaction against rss0 - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -514,15 +514,15 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndRollback(t *testing.T) { keyspace := "TestTxConn" sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, keyspace) - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} // Sequence the executes to ensure shard session order session := econtext.NewSafeSession(&vtgatepb.Session{InReservedConn: true}) // this will create reserved connections against all tablets - _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) - _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) wantSession := vtgatepb.Session{ @@ -550,7 +550,7 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndRollback(t *testing.T) { session.Session.InTransaction = true // start a transaction against rss0 - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -608,19 +608,19 @@ func TestTxConnCommitOrderFailure1(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, "TestTxConn") - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} queries := []*querypb.BoundQuery{{Sql: "query1"}} // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 err := sc.txConn.Commit(ctx, session) @@ -641,7 +641,7 @@ func TestTxConnCommitOrderFailure2(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, "TestTxConn") - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} queries := []*querypb.BoundQuery{{ Sql: "query1", @@ -649,13 +649,13 @@ func TestTxConnCommitOrderFailure2(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(context.Background(), nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(context.Background(), nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 err := sc.txConn.Commit(ctx, session) @@ -675,7 +675,7 @@ func TestTxConnCommitOrderFailure3(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, "TestTxConn") - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} queries := []*querypb.BoundQuery{{ Sql: "query1", @@ -683,13 +683,13 @@ func TestTxConnCommitOrderFailure3(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 require.NoError(t, @@ -717,7 +717,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, "TestTxConn") - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} queries := []*querypb.BoundQuery{{ Sql: "query1", @@ -725,7 +725,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -741,7 +741,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, PreSessions: []*vtgatepb.Session_ShardSession{{ @@ -766,7 +766,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, PreSessions: []*vtgatepb.Session_ShardSession{{ @@ -800,7 +800,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") // Ensure nothing changes if we reuse a transaction. - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) utils.MustMatch(t, &wantSession, session.Session, "Session") require.NoError(t, @@ -815,7 +815,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { ctx := utils.LeakCheckContext(t) sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, "TestTxConn") - sc.txConn.mode = vtgatepb.TransactionMode_MULTI + sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} queries := []*querypb.BoundQuery{{ Sql: "query1", @@ -823,7 +823,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -841,7 +841,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -869,7 +869,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -907,7 +907,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") // Ensure nothing changes if we reuse a transaction. - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) utils.MustMatch(t, &wantSession, session.Session, "Session") require.NoError(t, @@ -960,8 +960,8 @@ func TestTxConnCommit2PC(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PC") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) session.TransactionMode = vtgatepb.TransactionMode_TWOPC require.NoError(t, sc.txConn.Commit(ctx, session)) @@ -977,7 +977,7 @@ func TestTxConnCommit2PCOneParticipant(t *testing.T) { sc, sbc0, _, rss0, _, _ := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCOneParticipant") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.TransactionMode = vtgatepb.TransactionMode_TWOPC require.NoError(t, sc.txConn.Commit(ctx, session)) @@ -990,8 +990,8 @@ func TestTxConnCommit2PCCreateTransactionFail(t *testing.T) { sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCCreateTransactionFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailCreateTransaction = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1012,8 +1012,8 @@ func TestTxConnCommit2PCPrepareFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCPrepareFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailPrepare = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1038,8 +1038,8 @@ func TestTxConnCommit2PCStartCommitFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCStartCommitFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailStartCommit = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1057,8 +1057,8 @@ func TestTxConnCommit2PCStartCommitFail(t *testing.T) { sbc1.ResetCounter() session = econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) // Here the StartCommit failure is in uncertain state so rollback is not called and neither conclude. sbc0.MustFailStartCommitUncertain = 1 @@ -1080,8 +1080,8 @@ func TestTxConnCommit2PCCommitPreparedFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCCommitPreparedFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCommitPrepared = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1100,8 +1100,8 @@ func TestTxConnCommit2PCConcludeTransactionFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCConcludeTransactionFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailConcludeTransaction = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1120,8 +1120,8 @@ func TestTxConnRollback(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TxConnRollback") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) require.NoError(t, sc.txConn.Rollback(ctx, session)) wantSession := vtgatepb.Session{} @@ -1136,8 +1136,8 @@ func TestTxConnReservedRollback(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TxConnReservedRollback") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) require.NoError(t, sc.txConn.Rollback(ctx, session)) wantSession := vtgatepb.Session{ @@ -1173,8 +1173,8 @@ func TestTxConnReservedRollbackFailure(t *testing.T) { sc, sbc0, sbc1, rss0, rss1, rss01 := newTestTxConnEnv(t, ctx, "TxConnReservedRollback") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 assert.Error(t, diff --git a/go/vt/vtgate/vindexes/binary.go b/go/vt/vtgate/vindexes/binary.go index b78451ca1fb..96a72b2c3f4 100644 --- a/go/vt/vtgate/vindexes/binary.go +++ b/go/vt/vtgate/vindexes/binary.go @@ -30,6 +30,7 @@ var ( _ Reversible = (*Binary)(nil) _ Hashing = (*Binary)(nil) _ ParamValidating = (*Binary)(nil) + _ Sequential = (*Binary)(nil) ) // Binary is a vindex that converts binary bits to a keyspace id. @@ -108,6 +109,20 @@ func (*Binary) ReverseMap(_ VCursor, ksids [][]byte) ([]sqltypes.Value, error) { return reverseIds, nil } +// RangeMap can map ids to key.Destination objects. +func (vind *Binary) RangeMap(ctx context.Context, vcursor VCursor, startId sqltypes.Value, endId sqltypes.Value) ([]key.Destination, error) { + startKsId, err := vind.Hash(startId) + if err != nil { + return nil, err + } + endKsId, err := vind.Hash(endId) + if err != nil { + return nil, err + } + out := []key.Destination{&key.DestinationKeyRange{KeyRange: key.NewKeyRange(startKsId, endKsId)}} + return out, nil +} + // UnknownParams implements the ParamValidating interface. func (vind *Binary) UnknownParams() []string { return vind.unknownParams diff --git a/go/vt/vtgate/vindexes/binary_test.go b/go/vt/vtgate/vindexes/binary_test.go index 27ae6ceca11..a6556ec958a 100644 --- a/go/vt/vtgate/vindexes/binary_test.go +++ b/go/vt/vtgate/vindexes/binary_test.go @@ -24,6 +24,7 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" @@ -145,3 +146,18 @@ func TestBinaryReverseMap(t *testing.T) { t.Errorf("ReverseMap(): %v, want %s", err, wantErr) } } + +// TestBinaryRangeMap takes start and env values, +// and checks against a destination keyrange. +func TestBinaryRangeMap(t *testing.T) { + + startInterval := "0x01" + endInterval := "0x10" + + got, err := binOnlyVindex.(Sequential).RangeMap(context.Background(), nil, sqltypes.NewHexNum([]byte(startInterval)), + sqltypes.NewHexNum([]byte(endInterval))) + require.NoError(t, err) + want := "DestinationKeyRange(01-10)" + assert.Equal(t, want, got[0].String()) + +} diff --git a/go/vt/vtgate/vindexes/cached_size.go b/go/vt/vtgate/vindexes/cached_size.go index a97411a6ac8..ac68887c00d 100644 --- a/go/vt/vtgate/vindexes/cached_size.go +++ b/go/vt/vtgate/vindexes/cached_size.go @@ -175,6 +175,18 @@ func (cached *Keyspace) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Name))) return size } +func (cached *LookupCost) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(16) + } + // field LookupNonUnique *vitess.io/vitess/go/vt/vtgate/vindexes.LookupNonUnique + size += cached.LookupNonUnique.CachedSize(true) + return size +} func (cached *LookupHash) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -380,6 +392,24 @@ func (cached *Numeric) CachedSize(alloc bool) int64 { } return size } +func (cached *NumericLookupTable) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(8) + } + size += int64(48) + hmap := reflect.ValueOf(*cached) + numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) + numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) + size += hack.RuntimeAllocSize(int64(numOldBuckets * 144)) + if len(*cached) > 0 || numBuckets > 1 { + size += hack.RuntimeAllocSize(int64(numBuckets * 144)) + } + return size +} //go:nocheckptr func (cached *NumericStaticMap) CachedSize(alloc bool) int64 { @@ -470,6 +500,24 @@ func (cached *RegionJSON) CachedSize(alloc bool) int64 { } return size } +func (cached *RegionMap) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(8) + } + size += int64(48) + hmap := reflect.ValueOf(*cached) + numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) + numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) + size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) + if len(*cached) > 0 || numBuckets > 1 { + size += hack.RuntimeAllocSize(int64(numBuckets * 208)) + } + return size +} func (cached *ReverseBits) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vtgate/vindexes/lookup_cost.go b/go/vt/vtgate/vindexes/lookup_cost.go new file mode 100644 index 00000000000..6556032cea5 --- /dev/null +++ b/go/vt/vtgate/vindexes/lookup_cost.go @@ -0,0 +1,70 @@ +/* +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 vindexes + +import ( + "strconv" +) + +var ( + _ SingleColumn = (*LookupCost)(nil) + _ Lookup = (*LookupCost)(nil) + _ LookupPlanable = (*LookupCost)(nil) +) + +func init() { + Register("lookup_cost", newLookupCost) +} + +const defaultCost = 5 + +// LookupCost defines a test vindex that uses the cost provided by the user. +// This is a test vindex. +type LookupCost struct { + *LookupNonUnique + cost int +} + +// Cost returns the cost of this vindex as provided. +func (lc *LookupCost) Cost() int { + return lc.cost +} + +func newLookupCost(name string, m map[string]string) (Vindex, error) { + lookup, err := newLookup(name, m) + if err != nil { + return nil, err + } + cost := getInt(m, "cost", defaultCost) + return &LookupCost{ + LookupNonUnique: lookup.(*LookupNonUnique), + cost: cost, + }, nil + +} + +func getInt(m map[string]string, key string, defaultVal int) int { + val, ok := m[key] + if !ok { + return defaultVal + } + intVal, err := strconv.Atoi(val) + if err != nil { + return defaultVal + } + return intVal +} diff --git a/go/vt/vtgate/vindexes/numeric.go b/go/vt/vtgate/vindexes/numeric.go index 091807ec2cc..b40df13a997 100644 --- a/go/vt/vtgate/vindexes/numeric.go +++ b/go/vt/vtgate/vindexes/numeric.go @@ -31,6 +31,7 @@ var ( _ Reversible = (*Numeric)(nil) _ Hashing = (*Numeric)(nil) _ ParamValidating = (*Numeric)(nil) + _ Sequential = (*Numeric)(nil) ) // Numeric defines a bit-pattern mapping of a uint64 to the KeyspaceId. @@ -108,6 +109,20 @@ func (*Numeric) ReverseMap(_ VCursor, ksids [][]byte) ([]sqltypes.Value, error) return reverseIds, nil } +// RangeMap implements Between. +func (vind *Numeric) RangeMap(ctx context.Context, vcursor VCursor, startId sqltypes.Value, endId sqltypes.Value) ([]key.Destination, error) { + startKsId, err := vind.Hash(startId) + if err != nil { + return nil, err + } + endKsId, err := vind.Hash(endId) + if err != nil { + return nil, err + } + out := []key.Destination{&key.DestinationKeyRange{KeyRange: key.NewKeyRange(startKsId, endKsId)}} + return out, nil +} + // UnknownParams implements the ParamValidating interface. func (vind *Numeric) UnknownParams() []string { return vind.unknownParams diff --git a/go/vt/vtgate/vindexes/vindex.go b/go/vt/vtgate/vindexes/vindex.go index e3d5a6d7e4d..947877108e0 100644 --- a/go/vt/vtgate/vindexes/vindex.go +++ b/go/vt/vtgate/vindexes/vindex.go @@ -130,6 +130,13 @@ type ( ReverseMap(vcursor VCursor, ks [][]byte) ([]sqltypes.Value, error) } + // A Sequential vindex is an optional interface one that maps to a keyspace range + // instead of a single keyspace id. It's being used to reduce the fan out for + // 'BETWEEN' expressions. + Sequential interface { + RangeMap(ctx context.Context, vcursor VCursor, startId sqltypes.Value, endId sqltypes.Value) ([]key.Destination, error) + } + // A Prefixable vindex is one that maps the prefix of a id to a keyspace range // instead of a single keyspace id. It's being used to reduced the fan out for // 'LIKE' expressions. diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 3852bbfcde3..05081a3c9ba 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -25,10 +25,9 @@ import ( "strings" "time" - "vitess.io/vitess/go/ptr" - "vitess.io/vitess/go/json2" "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/ptr" "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -58,6 +57,7 @@ const ( TypeTable = "" TypeSequence = "sequence" TypeReference = "reference" + TypeView = "view" ) // VSchema represents the denormalized version of SrvVSchema, @@ -264,7 +264,7 @@ type KeyspaceSchema struct { ForeignKeyMode vschemapb.Keyspace_ForeignKeyMode Tables map[string]*Table Vindexes map[string]Vindex - Views map[string]sqlparser.SelectStatement + Views map[string]sqlparser.TableStatement Error error MultiTenantSpec *vschemapb.MultiTenantSpec @@ -431,16 +431,16 @@ func (vschema *VSchema) AddView(ksname, viewName, query string, parser *sqlparse if err != nil { return err } - selectStmt, ok := ast.(sqlparser.SelectStatement) + selectStmt, ok := ast.(sqlparser.TableStatement) if !ok { return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "expected SELECT or UNION query, got %T", ast) } if ks.Views == nil { - ks.Views = make(map[string]sqlparser.SelectStatement) + ks.Views = make(map[string]sqlparser.TableStatement) } ks.Views[viewName] = selectStmt t := &Table{ - Type: "View", + Type: TypeView, Name: sqlparser.NewIdentifierCS(viewName), Keyspace: ks.Keyspace, ColumnListAuthoritative: true, @@ -473,6 +473,40 @@ func buildGlobalTables(source *vschemapb.SrvVSchema, vschema *VSchema) { } } +// AddAdditionalGlobalTables adds unique tables from unsharded keyspaces to the global tables. +// It is expected to be called from the schema tracking code. Note that this is called after `BuildVSchema` +// which means that the global tables are already populated with the tables from the sharded keyspaces and from +// unsharded keyspaces which have tables specified in associated vschemas. +func AddAdditionalGlobalTables(source *vschemapb.SrvVSchema, vschema *VSchema) { + newTables := make(map[string]*Table) + + // Collect valid uniquely named tables from unsharded keyspaces. + for ksname, ks := range source.Keyspaces { + ksvschema := vschema.Keyspaces[ksname] + // Ignore sharded keyspaces and those flagged for explicit routing. + if ks.RequireExplicitRouting || ks.Sharded { + continue + } + for tname, table := range ksvschema.Tables { + // Ignore tables already global (i.e. if specified in the vschema of an unsharded keyspace) or ambiguous. + if _, found := vschema.globalTables[tname]; !found { + _, ok := newTables[tname] + if !ok { + table.Keyspace = ksvschema.Keyspace + newTables[tname] = table + } else { + newTables[tname] = nil + } + } + } + } + + // Mark new tables found just once as globally routable, rest as ambiguous. + for k, v := range newTables { + vschema.globalTables[k] = v + } +} + func buildKeyspaceGlobalTables(vschema *VSchema, ksvschema *KeyspaceSchema) { for tname, t := range ksvschema.Tables { if gt, ok := vschema.globalTables[tname]; ok { @@ -1443,7 +1477,7 @@ func (vschema *VSchema) FindTableOrVindex(keyspace, name string, tabletType topo return nil, nil, NotFoundError{TableName: name} } -func (vschema *VSchema) FindView(keyspace, name string) sqlparser.SelectStatement { +func (vschema *VSchema) FindView(keyspace, name string) sqlparser.TableStatement { if keyspace == "" { switch { case len(vschema.Keyspaces) == 1: diff --git a/go/vt/vtgate/vindexes/vschema_routing_test.go b/go/vt/vtgate/vindexes/vschema_routing_test.go new file mode 100644 index 00000000000..48ac9239fbb --- /dev/null +++ b/go/vt/vtgate/vindexes/vschema_routing_test.go @@ -0,0 +1,500 @@ +/* +Copyright 2025 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 vindexes + +import ( + "encoding/json" + "errors" + "sort" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + "vitess.io/vitess/go/vt/sqlparser" +) + +// TestAutoGlobalRoutingExtended tests the global routing of tables across various keyspace configurations, +// including unsharded and sharded keyspaces, with and without the RequireExplicitRouting flag. +func TestAutoGlobalRoutingExtended(t *testing.T) { + isTableGloballyRoutable := func(vschema *VSchema, tableName string) (isGlobal, isAmbiguous bool) { + table, err := vschema.FindTable("", tableName) + if err != nil { + if strings.Contains(err.Error(), "ambiguous") { + return false, true + } + return false, false + } + return table != nil, false + } + type testKeySpace struct { + name string + ks *vschemapb.Keyspace + } + unsharded1 := &testKeySpace{ + name: "unsharded1", + ks: &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "table1": {}, + "table2": {}, + "scommon1": {}, + "ucommon3": {}, + }, + }, + } + unsharded2 := &testKeySpace{ + name: "unsharded2", + ks: &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "table3": {}, + "table4": {}, + "scommon1": {}, + "scommon2": {}, + "ucommon3": {}, + }, + }, + } + sharded1 := &testKeySpace{ + name: "sharded1", + ks: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, + }, + Tables: map[string]*vschemapb.Table{ + "table5": {}, + "scommon1": {}, + "scommon2": {}, + }, + }, + } + sharded2 := &testKeySpace{ + name: "sharded2", + ks: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, + }, + Tables: map[string]*vschemapb.Table{ + "table6": {}, + "scommon2": {}, + "scommon3": {}, + }, + }, + } + for _, tables := range []*vschemapb.Keyspace{sharded1.ks, sharded2.ks} { + for _, t := range tables.Tables { + t.ColumnVindexes = append(t.ColumnVindexes, &vschemapb.ColumnVindex{ + Column: "c1", + Name: "xxhash", + }) + } + } + type testCase struct { + name string + keyspaces []*testKeySpace + expGlobalTables []string + expAmbiguousTables []string + explicit []string + } + testCases := []testCase{ + { + name: "no keyspaces", + keyspaces: []*testKeySpace{}, + expGlobalTables: nil, + expAmbiguousTables: nil, + }, + { + name: "one unsharded keyspace", + keyspaces: []*testKeySpace{unsharded1}, + expGlobalTables: []string{"table1", "table2", "scommon1", "ucommon3"}, + expAmbiguousTables: nil, + }, + { + name: "two unsharded keyspaces", + keyspaces: []*testKeySpace{unsharded1, unsharded2}, + expGlobalTables: []string{"table1", "table2", "table3", "table4", "scommon2"}, + expAmbiguousTables: []string{"scommon1", "ucommon3"}, + }, + { + name: "two unsharded keyspaces, one with RequireExplicitRouting", + keyspaces: []*testKeySpace{unsharded1, unsharded2}, + explicit: []string{"unsharded1"}, + expGlobalTables: []string{"table3", "table4", "scommon1", "scommon2", "ucommon3"}, + }, + { + name: "one sharded keyspace", + keyspaces: []*testKeySpace{sharded1}, + expGlobalTables: []string{"table5", "scommon1", "scommon2"}, + }, + { + name: "two sharded keyspaces", + keyspaces: []*testKeySpace{sharded1, sharded2}, + expGlobalTables: []string{"table5", "table6", "scommon1", "scommon3"}, + expAmbiguousTables: []string{"scommon2"}, + }, + { + name: "two sharded keyspaces, one with RequireExplicitRouting", + keyspaces: []*testKeySpace{sharded1, sharded2}, + explicit: []string{"sharded2"}, + expGlobalTables: []string{"table5", "scommon1", "scommon2"}, + }, + { + name: "two sharded keyspaces, both with RequireExplicitRouting", + keyspaces: []*testKeySpace{sharded1, sharded2}, + explicit: []string{"sharded1", "sharded2"}, + expGlobalTables: nil, + }, + { + name: "two sharded keyspaces, one unsharded keyspace", + keyspaces: []*testKeySpace{sharded1, sharded2, unsharded1}, + expGlobalTables: []string{"table1", "table2", "table5", "table6", "scommon3", "ucommon3"}, + expAmbiguousTables: []string{"scommon1", "scommon2"}, + }, + { + name: "two sharded keyspaces, one unsharded keyspace, one with RequireExplicitRouting", + keyspaces: []*testKeySpace{sharded1, sharded2, unsharded1, unsharded2}, + explicit: []string{"unsharded1"}, + expGlobalTables: []string{"table3", "table4", "table5", "table6", "scommon3", "ucommon3"}, + expAmbiguousTables: []string{"scommon1", "scommon2"}, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + allTables := make(map[string]bool) + source := &vschemapb.SrvVSchema{ + Keyspaces: make(map[string]*vschemapb.Keyspace), + } + for _, ks := range tc.keyspaces { + source.Keyspaces[ks.name] = ks.ks + // set it false for all keyspaces here and later override for those requested in the test case + ks.ks.RequireExplicitRouting = false + for tname := range ks.ks.Tables { + _, ok := allTables[tname] + if !ok { + allTables[tname] = true + } + } + } + for _, ksName := range tc.explicit { + source.Keyspaces[ksName].RequireExplicitRouting = true + } + vschema := BuildVSchema(source, sqlparser.NewTestParser()) + require.NotNil(t, vschema) + AddAdditionalGlobalTables(source, vschema) + + var globalTables, ambiguousTables []string + for tname := range allTables { + isGlobal, isAmbiguous := isTableGloballyRoutable(vschema, tname) + if isGlobal { + globalTables = append(globalTables, tname) + } else if isAmbiguous { + ambiguousTables = append(ambiguousTables, tname) + } + } + sort.Strings(globalTables) + sort.Strings(ambiguousTables) + sort.Strings(tc.expGlobalTables) + sort.Strings(tc.expAmbiguousTables) + require.EqualValuesf(t, tc.expGlobalTables, globalTables, "global tables mismatch") + require.EqualValuesf(t, tc.expAmbiguousTables, ambiguousTables, "ambiguous tables mismatch") + }) + } +} + +// TestAutoGlobalRouting tests adding tables in unsharded keyspaces to global routing if they don't have +// an associated VSchema which has the RequireExplicitRouting flag set. These tables should also not be +// already part of the global routing tables via the VSchema of sharded keyspaces. +func TestAutoGlobalRoutingBasic(t *testing.T) { + // Create two unsharded keyspaces and two sharded keyspaces, each with some common tables. + unsharded1 := &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "table1": {}, // unique, should be added to global routing + "table2": {}, // unique, should be added to global routing + "scommon1": {}, // common with sharded1, should not be added to global routing because it is already global because of sharded1 + "ucommon3": {}, // common with unsharded2, should not be added to global routing because it is ambiguous because of unsharded2 + }, + } + unsharded2 := &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "table3": {}, // unique, should be added to global routing + "table4": {}, // unique, should be added to global routing + "scommon1": {}, // common with sharded1, should not be added to global routing because it is already global because of sharded1 + "scommon2": {}, // common with sharded1, should not be added to global routing because it is already global because of sharded1 + "ucommon3": {}, // common with unsharded1, should not be added to global routing because it is ambiguous because of unsharded1 + }, + } + sharded1 := &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, + }, + Tables: map[string]*vschemapb.Table{ + "table5": {}, // unique, should be added to global routing + "scommon1": {}, // common with unsharded1 and unsharded2, should be added to global routing because it's in the vschema + "scommon2": {}, // common with unsharded2, not ambiguous because sharded2 sets RequireExplicitRouting + }, + } + sharded2 := &vschemapb.Keyspace{ + Sharded: true, + RequireExplicitRouting: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, + }, + // none should be considered for choice as global or ambiguous because of RequireExplicitRouting + Tables: map[string]*vschemapb.Table{ + "table6": {}, // unique + "scommon2": {}, // common with sharded1, but has RequireExplicitRouting + "scommon3": {}, // unique + }, + } + for _, ks := range []*vschemapb.Keyspace{sharded1, sharded2} { + for _, t := range ks.Tables { + t.ColumnVindexes = append(t.ColumnVindexes, &vschemapb.ColumnVindex{ + Column: "c1", + Name: "xxhash", + }) + } + } + source := &vschemapb.SrvVSchema{ + Keyspaces: map[string]*vschemapb.Keyspace{ + "sharded1": sharded1, + "sharded2": sharded2, + }, + } + + vschema := BuildVSchema(source, sqlparser.NewTestParser()) + require.NotNil(t, vschema) + + // Check table is global + mustRouteGlobally := func(t *testing.T, tname, ksName string) { + t.Helper() + _, err := vschema.FindTable("", tname) + require.NoError(t, err) + // The vtgate data structures don't always set the keyspace name, so cannot reliably check that at the moment. + _ = ksName + } + + mustNotRouteGlobally := func(t *testing.T, tname string) { + t.Helper() + _, err := vschema.FindTable("", tname) + require.Error(t, err) + } + + // Verify the global tables + ks := vschema.Keyspaces["sharded1"] + require.EqualValues(t, vschema.globalTables, map[string]*Table{ + "table5": ks.Tables["table5"], + "scommon1": ks.Tables["scommon1"], + "scommon2": ks.Tables["scommon2"], + }) + mustRouteGlobally(t, "table5", "sharded1") + mustRouteGlobally(t, "scommon1", "sharded1") + mustRouteGlobally(t, "scommon2", "sharded1") + + // Add unsharded keyspaces to SrvVSchema and build VSchema + var err error + source.Keyspaces["unsharded1"] = unsharded1 + source.Keyspaces["unsharded2"] = unsharded2 + vschema.Keyspaces["unsharded1"], err = BuildKeyspace(unsharded1, sqlparser.NewTestParser()) + require.NoError(t, err) + vschema.Keyspaces["unsharded2"], err = BuildKeyspace(unsharded2, sqlparser.NewTestParser()) + require.NoError(t, err) + + // Verify the global tables don't change + mustRouteGlobally(t, "table5", "sharded1") + mustRouteGlobally(t, "scommon1", "sharded1") + mustRouteGlobally(t, "scommon2", "sharded1") + + // Add additional global tables and then verify that the unsharded global tables are added + AddAdditionalGlobalTables(source, vschema) + + mustRouteGlobally(t, "table1", "unsharded1") + mustRouteGlobally(t, "table2", "unsharded1") + + mustRouteGlobally(t, "table3", "unsharded2") + mustRouteGlobally(t, "table4", "unsharded2") + mustNotRouteGlobally(t, "ucommon3") + + mustRouteGlobally(t, "scommon1", "sharded1") + mustRouteGlobally(t, "scommon2", "sharded1") + mustRouteGlobally(t, "table5", "sharded1") + + mustNotRouteGlobally(t, "table6") + mustNotRouteGlobally(t, "scommon3") +} + +func TestVSchemaRoutingRules(t *testing.T) { + input := vschemapb.SrvVSchema{ + RoutingRules: &vschemapb.RoutingRules{ + Rules: []*vschemapb.RoutingRule{{ + FromTable: "rt1", + ToTables: []string{"ks1.t1", "ks2.t2"}, + }, { + FromTable: "rt2", + ToTables: []string{"ks2.t2"}, + }, { + FromTable: "escaped", + ToTables: []string{"`ks2`.`t2`"}, + }, { + FromTable: "dup", + ToTables: []string{"ks1.t1"}, + }, { + FromTable: "dup", + ToTables: []string{"ks1.t1"}, + }, { + FromTable: "badname", + ToTables: []string{"t1.t2.t3"}, + }, { + FromTable: "unqualified", + ToTables: []string{"t1"}, + }, { + FromTable: "badkeyspace", + ToTables: []string{"ks3.t1"}, + }, { + FromTable: "notfound", + ToTables: []string{"ks1.t2"}, + }}, + }, + Keyspaces: map[string]*vschemapb.Keyspace{ + "ks1": { + Sharded: true, + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Vindexes: map[string]*vschemapb.Vindex{ + "stfu1": { + Type: "stfu", + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{ + { + Column: "c1", + Name: "stfu1", + }, + }, + }, + }, + }, + "ks2": { + ForeignKeyMode: vschemapb.Keyspace_managed, + Tables: map[string]*vschemapb.Table{ + "t2": {}, + }, + }, + }, + } + got := BuildVSchema(&input, sqlparser.NewTestParser()) + ks1 := &Keyspace{ + Name: "ks1", + Sharded: true, + } + ks2 := &Keyspace{ + Name: "ks2", + } + vindex1 := &stFU{ + name: "stfu1", + } + t1 := &Table{ + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: ks1, + ColumnVindexes: []*ColumnVindex{{ + Columns: []sqlparser.IdentifierCI{sqlparser.NewIdentifierCI("c1")}, + Type: "stfu", + Name: "stfu1", + Vindex: vindex1, + isUnique: vindex1.IsUnique(), + cost: vindex1.Cost(), + }}, + } + t1.Ordered = []*ColumnVindex{ + t1.ColumnVindexes[0], + } + t2 := &Table{ + Name: sqlparser.NewIdentifierCS("t2"), + Keyspace: ks2, + } + want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, + RoutingRules: map[string]*RoutingRule{ + "rt1": { + Error: errors.New("table rt1 has more than one target: [ks1.t1 ks2.t2]"), + }, + "rt2": { + Tables: []*Table{t2}, + }, + "escaped": { + Tables: []*Table{t2}, + }, + "dup": { + Error: errors.New("duplicate rule for entry dup"), + }, + "badname": { + Error: errors.New("invalid table name: 't1.t2.t3', it must be of the qualified form . (dots are not allowed in either name)"), + }, + "unqualified": { + Error: errors.New("invalid table name: 't1', it must be of the qualified form . (dots are not allowed in either name)"), + }, + "badkeyspace": { + Error: errors.New("VT05003: unknown database 'ks3' in vschema"), + }, + "notfound": { + Error: errors.New("table t2 not found"), + }, + }, + globalTables: map[string]*Table{ + "t1": t1, + "t2": t2, + }, + uniqueVindexes: map[string]Vindex{ + "stfu1": vindex1, + }, + Keyspaces: map[string]*KeyspaceSchema{ + "ks1": { + Keyspace: ks1, + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Tables: map[string]*Table{ + "t1": t1, + }, + Vindexes: map[string]Vindex{ + "stfu1": vindex1, + }, + }, + "ks2": { + ForeignKeyMode: vschemapb.Keyspace_managed, + Keyspace: ks2, + Tables: map[string]*Table{ + "t2": t2, + }, + Vindexes: map[string]Vindex{}, + }, + }, + } + gotb, _ := json.MarshalIndent(got, "", " ") + wantb, _ := json.MarshalIndent(want, "", " ") + assert.Equal(t, string(wantb), string(gotb), string(gotb)) +} diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index 25f8e135698..70e70745e9b 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -21,6 +21,7 @@ import ( "encoding/json" "errors" "fmt" + "os" "reflect" "strings" "testing" @@ -747,157 +748,6 @@ func TestShardedVSchemaOwnerInfo(t *testing.T) { } } -func TestVSchemaRoutingRules(t *testing.T) { - input := vschemapb.SrvVSchema{ - RoutingRules: &vschemapb.RoutingRules{ - Rules: []*vschemapb.RoutingRule{{ - FromTable: "rt1", - ToTables: []string{"ks1.t1", "ks2.t2"}, - }, { - FromTable: "rt2", - ToTables: []string{"ks2.t2"}, - }, { - FromTable: "escaped", - ToTables: []string{"`ks2`.`t2`"}, - }, { - FromTable: "dup", - ToTables: []string{"ks1.t1"}, - }, { - FromTable: "dup", - ToTables: []string{"ks1.t1"}, - }, { - FromTable: "badname", - ToTables: []string{"t1.t2.t3"}, - }, { - FromTable: "unqualified", - ToTables: []string{"t1"}, - }, { - FromTable: "badkeyspace", - ToTables: []string{"ks3.t1"}, - }, { - FromTable: "notfound", - ToTables: []string{"ks1.t2"}, - }}, - }, - Keyspaces: map[string]*vschemapb.Keyspace{ - "ks1": { - Sharded: true, - ForeignKeyMode: vschemapb.Keyspace_unmanaged, - Vindexes: map[string]*vschemapb.Vindex{ - "stfu1": { - Type: "stfu", - }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{ - { - Column: "c1", - Name: "stfu1", - }, - }, - }, - }, - }, - "ks2": { - ForeignKeyMode: vschemapb.Keyspace_managed, - Tables: map[string]*vschemapb.Table{ - "t2": {}, - }, - }, - }, - } - got := BuildVSchema(&input, sqlparser.NewTestParser()) - ks1 := &Keyspace{ - Name: "ks1", - Sharded: true, - } - ks2 := &Keyspace{ - Name: "ks2", - } - vindex1 := &stFU{ - name: "stfu1", - } - t1 := &Table{ - Name: sqlparser.NewIdentifierCS("t1"), - Keyspace: ks1, - ColumnVindexes: []*ColumnVindex{{ - Columns: []sqlparser.IdentifierCI{sqlparser.NewIdentifierCI("c1")}, - Type: "stfu", - Name: "stfu1", - Vindex: vindex1, - isUnique: vindex1.IsUnique(), - cost: vindex1.Cost(), - }}, - } - t1.Ordered = []*ColumnVindex{ - t1.ColumnVindexes[0], - } - t2 := &Table{ - Name: sqlparser.NewIdentifierCS("t2"), - Keyspace: ks2, - } - want := &VSchema{ - MirrorRules: map[string]*MirrorRule{}, - RoutingRules: map[string]*RoutingRule{ - "rt1": { - Error: errors.New("table rt1 has more than one target: [ks1.t1 ks2.t2]"), - }, - "rt2": { - Tables: []*Table{t2}, - }, - "escaped": { - Tables: []*Table{t2}, - }, - "dup": { - Error: errors.New("duplicate rule for entry dup"), - }, - "badname": { - Error: errors.New("invalid table name: 't1.t2.t3', it must be of the qualified form . (dots are not allowed in either name)"), - }, - "unqualified": { - Error: errors.New("invalid table name: 't1', it must be of the qualified form . (dots are not allowed in either name)"), - }, - "badkeyspace": { - Error: errors.New("VT05003: unknown database 'ks3' in vschema"), - }, - "notfound": { - Error: errors.New("table t2 not found"), - }, - }, - globalTables: map[string]*Table{ - "t1": t1, - "t2": t2, - }, - uniqueVindexes: map[string]Vindex{ - "stfu1": vindex1, - }, - Keyspaces: map[string]*KeyspaceSchema{ - "ks1": { - Keyspace: ks1, - ForeignKeyMode: vschemapb.Keyspace_unmanaged, - Tables: map[string]*Table{ - "t1": t1, - }, - Vindexes: map[string]Vindex{ - "stfu1": vindex1, - }, - }, - "ks2": { - ForeignKeyMode: vschemapb.Keyspace_managed, - Keyspace: ks2, - Tables: map[string]*Table{ - "t2": t2, - }, - Vindexes: map[string]Vindex{}, - }, - }, - } - gotb, _ := json.MarshalIndent(got, "", " ") - wantb, _ := json.MarshalIndent(want, "", " ") - assert.Equal(t, string(wantb), string(gotb), string(gotb)) -} - func TestVSchemaMirrorRules(t *testing.T) { input := vschemapb.SrvVSchema{ MirrorRules: &vschemapb.MirrorRules{ @@ -3551,6 +3401,20 @@ func TestFindTableWithSequences(t *testing.T) { } } +func TestGlobalTables(t *testing.T) { + input, err := os.ReadFile("../planbuilder/testdata/vschemas/schema.json") + require.NoError(t, err) + + var vs vschemapb.SrvVSchema + err = json2.UnmarshalPB(input, &vs) + require.NoError(t, err) + + got := BuildVSchema(&vs, sqlparser.NewTestParser()) + tbl, err := got.findGlobalTable("user", false) + require.NoError(t, err) + assert.NotNil(t, tbl) +} + func vindexNames(vindexes []*ColumnVindex) (result []string) { for _, vindex := range vindexes { result = append(result, vindex.Name) diff --git a/go/vt/vtgate/viper_config.go b/go/vt/vtgate/viper_config.go new file mode 100644 index 00000000000..68430b7be2c --- /dev/null +++ b/go/vt/vtgate/viper_config.go @@ -0,0 +1,50 @@ +/* +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 vtgate + +import ( + "vitess.io/vitess/go/viperutil" + vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" +) + +// DynamicViperConfig is a dynamic config that uses viper. +type DynamicViperConfig struct { + onlineDDL viperutil.Value[bool] + directDDL viperutil.Value[bool] + txMode viperutil.Value[vtgatepb.TransactionMode] +} + +// NewDynamicViperConfig creates a new dynamic viper config +func NewDynamicViperConfig() *DynamicViperConfig { + return &DynamicViperConfig{ + onlineDDL: enableOnlineDDL, + directDDL: enableDirectDDL, + txMode: transactionMode, + } +} + +func (d *DynamicViperConfig) OnlineEnabled() bool { + return d.onlineDDL.Get() +} + +func (d *DynamicViperConfig) DirectEnabled() bool { + return d.directDDL.Get() +} + +func (d *DynamicViperConfig) TransactionMode() vtgatepb.TransactionMode { + return d.txMode.Get() +} diff --git a/go/vt/vtgate/viperconfig.go b/go/vt/vtgate/viperconfig.go deleted file mode 100644 index ec77ff62d4f..00000000000 --- a/go/vt/vtgate/viperconfig.go +++ /dev/null @@ -1,16 +0,0 @@ -package vtgate - -import "vitess.io/vitess/go/viperutil" - -type dynamicViperConfig struct { - onlineDDL viperutil.Value[bool] - directDDL viperutil.Value[bool] -} - -func (d *dynamicViperConfig) OnlineEnabled() bool { - return d.onlineDDL.Get() -} - -func (d *dynamicViperConfig) DirectEnabled() bool { - return d.directDDL.Get() -} diff --git a/go/vt/vtgate/vschema_manager.go b/go/vt/vtgate/vschema_manager.go index 62ea2cd3455..e73bff4c196 100644 --- a/go/vt/vtgate/vschema_manager.go +++ b/go/vt/vtgate/vschema_manager.go @@ -18,11 +18,11 @@ package vtgate import ( "context" + "errors" "sync" "vitess.io/vitess/go/vt/graph" "vitess.io/vitess/go/vt/log" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/srvtopo" @@ -30,9 +30,14 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/vindexes" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) +// The full SQL error that the user sees in their vtgate connection looks like this: +// failed to update vschema as the session's version was stale; please try again (errno 1105) (sqlstate HY000) during query: ALTER VSCHEMA DROP TABLE t864 +var ErrStaleVSchema = errors.New("failed to update vschema as the session's version was stale; please try again") + // VSchemaManager is used to watch for updates to the vschema and to implement // the DDL commands to add / remove vindexes type VSchemaManager struct { @@ -49,7 +54,7 @@ type VSchemaManager struct { // SchemaInfo is an interface to schema tracker. type SchemaInfo interface { Tables(ks string) map[string]*vindexes.TableInfo - Views(ks string) map[string]sqlparser.SelectStatement + Views(ks string) map[string]sqlparser.TableStatement UDFs(ks string) []string } @@ -64,21 +69,23 @@ func (vm *VSchemaManager) GetCurrentSrvVschema() *vschemapb.SrvVSchema { // UpdateVSchema propagates the updated vschema to the topo. The entry for // the given keyspace is updated in the global topo, and the full SrvVSchema // is updated in all known cells. -func (vm *VSchemaManager) UpdateVSchema(ctx context.Context, ksName string, vschema *vschemapb.SrvVSchema) error { +func (vm *VSchemaManager) UpdateVSchema(ctx context.Context, ks *topo.KeyspaceVSchemaInfo, srv *vschemapb.SrvVSchema) error { topoServer, err := vm.serv.GetTopoServer() if err != nil { return err } - ks := vschema.Keyspaces[ksName] - - _, err = vindexes.BuildKeyspace(ks, vm.parser) + _, err = vindexes.BuildKeyspace(ks.Keyspace, vm.parser) if err != nil { return err } - err = topoServer.SaveVSchema(ctx, ksName, ks) + err = topoServer.SaveVSchema(ctx, ks) if err != nil { + if topo.IsErrType(err, topo.BadVersion) { + // Provide a more useful error message to the user. + return ErrStaleVSchema + } return err } @@ -89,7 +96,7 @@ func (vm *VSchemaManager) UpdateVSchema(ctx context.Context, ksName string, vsch // even if one cell fails, continue to try the others for _, cell := range cells { - cellErr := topoServer.UpdateSrvVSchema(ctx, cell, vschema) + cellErr := topoServer.UpdateSrvVSchema(ctx, cell, srv) if cellErr != nil { err = cellErr log.Errorf("error updating vschema in cell %s: %v", cell, cellErr) @@ -100,7 +107,7 @@ func (vm *VSchemaManager) UpdateVSchema(ctx context.Context, ksName string, vsch } // Update all the local copy of VSchema if the topo update is successful. - vm.VSchemaUpdate(vschema, err) + vm.VSchemaUpdate(srv, err) return nil } @@ -194,27 +201,44 @@ func (vm *VSchemaManager) buildAndEnhanceVSchema(v *vschemapb.SrvVSchema) *vinde // We mark the keyspaces that have foreign key management in Vitess and have cyclic foreign keys // to have an error. This makes all queries against them to fail. markErrorIfCyclesInFk(vschema) + // Add tables from schema tracking into globally routable tables, if they are not already present. + // We need to skip if already present, to handle the case where MoveTables has switched traffic + // and removed the source vschema but not from the source database because user asked to --keep-data + vindexes.AddAdditionalGlobalTables(v, vschema) } return vschema } func (vm *VSchemaManager) updateFromSchema(vschema *vindexes.VSchema) { for ksName, ks := range vschema.Keyspaces { - vm.updateTableInfo(vschema, ks, ksName) vm.updateViewInfo(ks, ksName) + vm.updateTableInfo(vschema, ks, ksName) vm.updateUDFsInfo(ks, ksName) } } func (vm *VSchemaManager) updateViewInfo(ks *vindexes.KeyspaceSchema, ksName string) { views := vm.schema.Views(ksName) - if views != nil { - ks.Views = make(map[string]sqlparser.SelectStatement, len(views)) - for name, def := range views { - ks.Views[name] = sqlparser.Clone(def) + if views == nil { + return + } + ks.Views = make(map[string]sqlparser.TableStatement, len(views)) + for name, def := range views { + ks.Views[name] = sqlparser.Clone(def) + vTbl, ok := ks.Tables[name] + if ok { + vTbl.Type = vindexes.TypeView + } else { + // Adding view to the VSchema as a table. + ks.Tables[name] = &vindexes.Table{ + Type: vindexes.TypeView, + Name: sqlparser.NewIdentifierCS(name), + Keyspace: ks.Keyspace, + } } } } + func (vm *VSchemaManager) updateTableInfo(vschema *vindexes.VSchema, ks *vindexes.KeyspaceSchema, ksName string) { m := vm.schema.Tables(ksName) // Before we add the foreign key definitions in the tables, we need to make sure that all the tables diff --git a/go/vt/vtgate/vschema_manager_test.go b/go/vt/vtgate/vschema_manager_test.go index 8db0c2df05b..b4b7a20804f 100644 --- a/go/vt/vtgate/vschema_manager_test.go +++ b/go/vt/vtgate/vschema_manager_test.go @@ -900,7 +900,7 @@ func (f *fakeSchema) Tables(string) map[string]*vindexes.TableInfo { return f.t } -func (f *fakeSchema) Views(string) map[string]sqlparser.SelectStatement { +func (f *fakeSchema) Views(string) map[string]sqlparser.TableStatement { return nil } func (f *fakeSchema) UDFs(string) []string { return f.udfs } diff --git a/go/vt/vtgate/vschemaacl/vschemaacl.go b/go/vt/vtgate/vschemaacl/vschemaacl.go index 5345d1437fc..08f6c2b0cd4 100644 --- a/go/vt/vtgate/vschemaacl/vschemaacl.go +++ b/go/vt/vtgate/vschemaacl/vschemaacl.go @@ -18,26 +18,67 @@ package vschemaacl import ( "strings" - "sync" "github.com/spf13/pflag" + "github.com/spf13/viper" - "vitess.io/vitess/go/vt/servenv" - + "vitess.io/vitess/go/viperutil" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/servenv" ) -var ( - // AuthorizedDDLUsers specifies the users that can perform ddl operations - AuthorizedDDLUsers string - - // ddlAllowAll is true if the special value of "*" was specified +type authorizedDDLUsers struct { allowAll bool + acl map[string]struct{} + source string +} + +func NewAuthorizedDDLUsers(users string) *authorizedDDLUsers { + acl := make(map[string]struct{}) + allowAll := false + + switch users { + case "": + case "%": + allowAll = true + default: + for _, user := range strings.Split(users, ",") { + user = strings.TrimSpace(user) + acl[user] = struct{}{} + } + } + + return &authorizedDDLUsers{ + allowAll: allowAll, + acl: acl, + source: users, + } +} - // ddlACL contains a set of allowed usernames - acl map[string]struct{} +func (a *authorizedDDLUsers) String() string { + return a.source +} - initMu sync.Mutex +var ( + // AuthorizedDDLUsers specifies the users that can perform ddl operations + AuthorizedDDLUsers = viperutil.Configure( + "vschema_ddl_authorized_users", + viperutil.Options[*authorizedDDLUsers]{ + FlagName: "vschema_ddl_authorized_users", + Default: &authorizedDDLUsers{}, + Dynamic: true, + GetFunc: func(v *viper.Viper) func(key string) *authorizedDDLUsers { + return func(key string) *authorizedDDLUsers { + newVal := v.GetString(key) + curVal, ok := v.Get(key).(*authorizedDDLUsers) + if ok && newVal == curVal.source { + return curVal + } + return NewAuthorizedDDLUsers(newVal) + } + }, + }, + ) ) // RegisterSchemaACLFlags installs log flags on the given FlagSet. @@ -46,7 +87,8 @@ var ( // calls this function, or call this function directly before parsing // command-line arguments. func RegisterSchemaACLFlags(fs *pflag.FlagSet) { - fs.StringVar(&AuthorizedDDLUsers, "vschema_ddl_authorized_users", AuthorizedDDLUsers, "List of users authorized to execute vschema ddl operations, or '%' to allow all users.") + fs.String("vschema_ddl_authorized_users", "", "List of users authorized to execute vschema ddl operations, or '%' to allow all users.") + viperutil.BindFlags(fs, AuthorizedDDLUsers) } func init() { @@ -55,33 +97,14 @@ func init() { } } -// Init parses the users option and sets allowAll / acl accordingly -func Init() { - initMu.Lock() - defer initMu.Unlock() - acl = make(map[string]struct{}) - allowAll = false - - if AuthorizedDDLUsers == "%" { - allowAll = true - return - } else if AuthorizedDDLUsers == "" { - return - } - - for _, user := range strings.Split(AuthorizedDDLUsers, ",") { - user = strings.TrimSpace(user) - acl[user] = struct{}{} - } -} - // Authorized returns true if the given caller is allowed to execute vschema operations func Authorized(caller *querypb.VTGateCallerID) bool { - if allowAll { + users := AuthorizedDDLUsers.Get() + if users.allowAll { return true } user := caller.GetUsername() - _, ok := acl[user] + _, ok := users.acl[user] return ok } diff --git a/go/vt/vtgate/vschemaacl/vschemaacl_test.go b/go/vt/vtgate/vschemaacl/vschemaacl_test.go index faa2dbfc294..cfd1de705af 100644 --- a/go/vt/vtgate/vschemaacl/vschemaacl_test.go +++ b/go/vt/vtgate/vschemaacl/vschemaacl_test.go @@ -35,8 +35,7 @@ func TestVschemaAcl(t *testing.T) { } // Test wildcard - AuthorizedDDLUsers = "%" - Init() + AuthorizedDDLUsers.Set(NewAuthorizedDDLUsers("%")) if !Authorized(&redUser) { t.Errorf("user should be authorized") @@ -46,8 +45,7 @@ func TestVschemaAcl(t *testing.T) { } // Test user list - AuthorizedDDLUsers = "oneUser, twoUser, redUser, blueUser" - Init() + AuthorizedDDLUsers.Set(NewAuthorizedDDLUsers("oneUser, twoUser, redUser, blueUser")) if !Authorized(&redUser) { t.Errorf("user should be authorized") @@ -57,8 +55,7 @@ func TestVschemaAcl(t *testing.T) { } // Revert to baseline state for other tests - AuthorizedDDLUsers = "" - Init() + AuthorizedDDLUsers.Set(NewAuthorizedDDLUsers("")) // By default no users are allowed in if Authorized(&redUser) { diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 8bab05479dd..8b8302d77d4 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -29,6 +29,7 @@ import ( "time" "github.com/spf13/pflag" + "github.com/spf13/viper" "vitess.io/vitess/go/acl" "vitess.io/vitess/go/sqltypes" @@ -60,7 +61,6 @@ import ( ) var ( - transactionMode = "MULTI" normalizeQueries = true streamBufferSize = 32 * 1024 @@ -114,9 +114,36 @@ var ( }, ) + transactionMode = viperutil.Configure( + "transaction_mode", + viperutil.Options[vtgatepb.TransactionMode]{ + FlagName: "transaction_mode", + Default: vtgatepb.TransactionMode_MULTI, + Dynamic: true, + GetFunc: func(v *viper.Viper) func(key string) vtgatepb.TransactionMode { + return func(key string) vtgatepb.TransactionMode { + txMode := v.GetString(key) + switch strings.ToLower(txMode) { + case "single": + return vtgatepb.TransactionMode_SINGLE + case "multi": + return vtgatepb.TransactionMode_MULTI + case "twopc": + return vtgatepb.TransactionMode_TWOPC + default: + fmt.Printf("Invalid option: %v\n", txMode) + fmt.Println("Usage: -transaction_mode {SINGLE | MULTI | TWOPC}") + os.Exit(1) + return -1 + } + } + }, + }, + ) + // schema tracking flags enableSchemaChangeSignal = true - enableViews bool + enableViews = true enableUdfs bool // vtgate views flags @@ -138,7 +165,7 @@ var ( ) func registerFlags(fs *pflag.FlagSet) { - fs.StringVar(&transactionMode, "transaction_mode", transactionMode, "SINGLE: disallow multi-db transactions, MULTI: allow multi-db transactions with best effort commit, TWOPC: allow multi-db transactions with 2pc commit") + fs.String("transaction_mode", "MULTI", "SINGLE: disallow multi-db transactions, MULTI: allow multi-db transactions with best effort commit, TWOPC: allow multi-db transactions with 2pc commit") fs.BoolVar(&normalizeQueries, "normalize_queries", normalizeQueries, "Rewrite queries with bind vars. Turn this off if the app itself sends normalized queries with bind vars.") fs.BoolVar(&terseErrors, "vtgate-config-terse-errors", terseErrors, "prevent bind vars from escaping in returned errors") fs.IntVar(&truncateErrorLen, "truncate-error-len", truncateErrorLen, "truncate errors sent to client if they are longer than this value (0 means do not truncate)") @@ -173,7 +200,11 @@ func registerFlags(fs *pflag.FlagSet) { fs.IntVar(&warmingReadsConcurrency, "warming-reads-concurrency", 500, "Number of concurrent warming reads allowed") fs.DurationVar(&warmingReadsQueryTimeout, "warming-reads-query-timeout", 5*time.Second, "Timeout of warming read queries") - viperutil.BindFlags(fs, enableOnlineDDL, enableDirectDDL) + viperutil.BindFlags(fs, + enableOnlineDDL, + enableDirectDDL, + transactionMode, + ) } func init() { @@ -181,25 +212,6 @@ func init() { servenv.OnParseFor("vtcombo", registerFlags) } -func getTxMode() vtgatepb.TransactionMode { - switch strings.ToLower(transactionMode) { - case "single": - log.Infof("Transaction mode: '%s'", transactionMode) - return vtgatepb.TransactionMode_SINGLE - case "multi": - log.Infof("Transaction mode: '%s'", transactionMode) - return vtgatepb.TransactionMode_MULTI - case "twopc": - log.Infof("Transaction mode: '%s'", transactionMode) - return vtgatepb.TransactionMode_TWOPC - default: - fmt.Printf("Invalid option: %v\n", transactionMode) - fmt.Println("Usage: -transaction_mode {SINGLE | MULTI | TWOPC}") - os.Exit(1) - return -1 - } -} - var ( // vschemaCounters needs to be initialized before planner to // catch the initial load stats. @@ -287,6 +299,8 @@ func Init( log.Fatalf("tabletGateway.WaitForTablets failed: %v", err) } + dynamicConfig := NewDynamicViperConfig() + // If we want to filter keyspaces replace the srvtopo.Server with a // filtering server if discovery.FilteringKeyspaces() { @@ -301,7 +315,7 @@ func Init( if _, err := schema.ParseDDLStrategy(defaultDDLStrategy); err != nil { log.Fatalf("Invalid value for -ddl_strategy: %v", err.Error()) } - tc := NewTxConn(gw, getTxMode()) + tc := NewTxConn(gw, dynamicConfig) // ScatterConn depends on TxConn to perform forced rollbacks. sc := NewScatterConn("VttabletCall", tc, gw) // TxResolver depends on TxConn to complete distributed transaction. @@ -338,21 +352,15 @@ func Init( plans := DefaultPlanCache() - executor := NewExecutor( - ctx, - env, - serv, - cell, - resolver, - normalizeQueries, - warnShardedOnly, - streamBufferSize, - plans, - si, - noScatter, - pv, - warmingReadsPercent, - ) + eConfig := ExecutorConfig{ + Normalize: normalizeQueries, + StreamSize: streamBufferSize, + AllowScatter: !noScatter, + WarmingReadsPercent: warmingReadsPercent, + QueryLogToFile: queryLogToFile, + } + + executor := NewExecutor(ctx, env, serv, cell, resolver, eConfig, warnShardedOnly, plans, si, pv, dynamicConfig) if err := executor.defaultQueryLogger(); err != nil { log.Fatalf("error initializing query logger: %v", err) diff --git a/go/vt/vtgate/vtgate_test.go b/go/vt/vtgate/vtgate_test.go index c113ed16308..f05f63474d0 100644 --- a/go/vt/vtgate/vtgate_test.go +++ b/go/vt/vtgate/vtgate_test.go @@ -715,8 +715,7 @@ func createVtgateEnv(t testing.TB) (*VTGate, *sandboxconn.SandboxConn, context.C cell := "aa" sb := createSandbox(KsTestSharded) sb.ShardSpec = "-" - executor, _, _, sbc, ctx := createExecutorEnv(t) - executor.normalize = normalizeQueries + executor, _, _, sbc, ctx := createExecutorEnvWithConfig(t, createExecutorConfigWithNormalizer()) vsm := newVStreamManager(executor.resolver.resolver, executor.serv, cell) vtg := newVTGate(executor, executor.resolver, vsm, nil, executor.scatterConn.gateway) diff --git a/go/vt/vtorc/config/config.go b/go/vt/vtorc/config/config.go index cafff5acce8..db367673aeb 100644 --- a/go/vt/vtorc/config/config.go +++ b/go/vt/vtorc/config/config.go @@ -174,6 +174,15 @@ var ( Dynamic: true, }, ) + + enablePrimaryDiskStalledRecovery = viperutil.Configure( + "enable-primary-disk-stalled-recovery", + viperutil.Options[bool]{ + FlagName: "enable-primary-disk-stalled-recovery", + Default: false, + Dynamic: true, + }, + ) ) func init() { @@ -197,6 +206,7 @@ func registerFlags(fs *pflag.FlagSet) { fs.Duration("recovery-poll-duration", recoveryPollDuration.Default(), "Timer duration on which VTOrc polls its database to run a recovery") fs.Bool("allow-emergency-reparent", ersEnabled.Default(), "Whether VTOrc should be allowed to run emergency reparent operation when it detects a dead primary") fs.Bool("change-tablets-with-errant-gtid-to-drained", convertTabletsWithErrantGTIDs.Default(), "Whether VTOrc should be changing the type of tablets with errant GTIDs to DRAINED") + fs.Bool("enable-primary-disk-stalled-recovery", enablePrimaryDiskStalledRecovery.Default(), "Whether VTOrc should detect a stalled disk on the primary and failover") viperutil.BindFlags(fs, instancePollTime, @@ -214,6 +224,7 @@ func registerFlags(fs *pflag.FlagSet) { recoveryPollDuration, ersEnabled, convertTabletsWithErrantGTIDs, + enablePrimaryDiskStalledRecovery, ) } @@ -332,6 +343,11 @@ func SetConvertTabletWithErrantGTIDs(val bool) { convertTabletsWithErrantGTIDs.Set(val) } +// GetStalledDiskPrimaryRecovery reports whether VTOrc is allowed to check for and recovery stalled disk problems. +func GetStalledDiskPrimaryRecovery() bool { + return enablePrimaryDiskStalledRecovery.Get() +} + // MarkConfigurationLoaded is called once configuration has first been loaded. // Listeners on ConfigurationLoaded will get a notification func MarkConfigurationLoaded() { diff --git a/go/vt/vtorc/db/generate_base.go b/go/vt/vtorc/db/generate_base.go index f997dc6ac0a..8baa9a12476 100644 --- a/go/vt/vtorc/db/generate_base.go +++ b/go/vt/vtorc/db/generate_base.go @@ -69,10 +69,8 @@ CREATE TABLE database_instance ( last_sql_error TEXT not null default '', last_io_error TEXT not null default '', oracle_gtid TINYint not null default 0, - mariadb_gtid TINYint not null default 0, relay_log_file varchar(128) not null default '', relay_log_pos bigint not null default 0, - pseudo_gtid TINYint not null default 0, replication_depth TINYint not null default 0, has_replication_filters TINYint not null default 0, data_center varchar(32) not null default '', @@ -107,6 +105,7 @@ CREATE TABLE database_instance ( semi_sync_primary_status TINYint NOT NULL DEFAULT 0, semi_sync_replica_status TINYint NOT NULL DEFAULT 0, semi_sync_primary_clients int NOT NULL DEFAULT 0, + is_disk_stalled TINYint NOT NULL DEFAULT 0, PRIMARY KEY (alias) )`, ` diff --git a/go/vt/vtorc/discovery/queue.go b/go/vt/vtorc/discovery/queue.go index 4b18303959b..bf279b781f2 100644 --- a/go/vt/vtorc/discovery/queue.go +++ b/go/vt/vtorc/discovery/queue.go @@ -33,12 +33,6 @@ import ( "vitess.io/vitess/go/vt/vtorc/config" ) -// QueueMetric contains the queue's active and queued sizes -type QueueMetric struct { - Active int - Queued int -} - // Queue contains information for managing discovery requests type Queue struct { sync.Mutex @@ -48,67 +42,16 @@ type Queue struct { queue chan string queuedKeys map[string]time.Time consumedKeys map[string]time.Time - metrics []QueueMetric -} - -// DiscoveryQueue contains the discovery queue which can then be accessed via an API call for monitoring. -// Currently this is accessed by ContinuousDiscovery() but also from http api calls. -// I may need to protect this better? -var discoveryQueue map[string](*Queue) -var dcLock sync.Mutex - -func init() { - discoveryQueue = make(map[string](*Queue)) } -// CreateOrReturnQueue allows for creation of a new discovery queue or -// returning a pointer to an existing one given the name. -func CreateOrReturnQueue(name string) *Queue { - dcLock.Lock() - defer dcLock.Unlock() - if q, found := discoveryQueue[name]; found { - return q - } - - q := &Queue{ +// CreateQueue allows for creation of a new discovery queue +func CreateQueue(name string) *Queue { + return &Queue{ name: name, queuedKeys: make(map[string]time.Time), consumedKeys: make(map[string]time.Time), queue: make(chan string, config.DiscoveryQueueCapacity), } - go q.startMonitoring() - - discoveryQueue[name] = q - - return q -} - -// monitoring queue sizes until we are told to stop -func (q *Queue) startMonitoring() { - log.Infof("Queue.startMonitoring(%s)", q.name) - ticker := time.NewTicker(time.Second) // hard-coded at every second - - for { - select { - case <-ticker.C: // do the periodic expiry - q.collectStatistics() - case <-q.done: - return - } - } -} - -// do a check of the entries in the queue, both those active and queued -func (q *Queue) collectStatistics() { - q.Lock() - defer q.Unlock() - - q.metrics = append(q.metrics, QueueMetric{Queued: len(q.queuedKeys), Active: len(q.consumedKeys)}) - - // remove old entries if we get too big - if len(q.metrics) > config.DiscoveryQueueMaxStatisticsSize { - q.metrics = q.metrics[len(q.metrics)-config.DiscoveryQueueMaxStatisticsSize:] - } } // QueueLen returns the length of the queue (channel size + queued size) diff --git a/go/vt/vtorc/inst/analysis.go b/go/vt/vtorc/inst/analysis.go index 3e9e81c5c9f..6a800e5ee0b 100644 --- a/go/vt/vtorc/inst/analysis.go +++ b/go/vt/vtorc/inst/analysis.go @@ -56,6 +56,7 @@ const ( LockedSemiSyncPrimaryHypothesis AnalysisCode = "LockedSemiSyncPrimaryHypothesis" LockedSemiSyncPrimary AnalysisCode = "LockedSemiSyncPrimary" ErrantGTIDDetected AnalysisCode = "ErrantGTIDDetected" + PrimaryDiskStalled AnalysisCode = "PrimaryDiskStalled" ) type StructureAnalysisCode string @@ -108,7 +109,6 @@ type ReplicationAnalysis struct { Description string StructureAnalysis []StructureAnalysisCode OracleGTIDImmediateTopology bool - MariaDBGTIDImmediateTopology bool BinlogServerImmediateTopology bool SemiSyncPrimaryEnabled bool SemiSyncPrimaryStatus bool @@ -130,6 +130,7 @@ type ReplicationAnalysis struct { MaxReplicaGTIDMode string MaxReplicaGTIDErrant string IsReadOnly bool + IsDiskStalled bool } func (replicationAnalysis *ReplicationAnalysis) MarshalJSON() ([]byte, error) { diff --git a/go/vt/vtorc/inst/analysis_dao.go b/go/vt/vtorc/inst/analysis_dao.go index 07830bf7dda..d487973b0f0 100644 --- a/go/vt/vtorc/inst/analysis_dao.go +++ b/go/vt/vtorc/inst/analysis_dao.go @@ -30,7 +30,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" - "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/config" "vitess.io/vitess/go/vt/vtorc/db" "vitess.io/vitess/go/vt/vtorc/util" @@ -54,7 +54,7 @@ type clusterAnalysis struct { hasClusterwideAction bool totalTablets int primaryAlias string - durability reparentutil.Durabler + durability policy.Durabler } // GetReplicationAnalysis will check for replication problems (dead primary; unreachable primary; etc) @@ -79,7 +79,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna vitess_keyspace.durability_policy AS durability_policy, vitess_shard.primary_timestamp AS shard_primary_term_timestamp, primary_instance.read_only AS read_only, - MIN(primary_instance.gtid_errant) AS gtid_errant, + MIN(primary_instance.gtid_errant) AS gtid_errant, MIN(primary_instance.alias) IS NULL AS is_invalid, MIN(primary_instance.binary_log_file) AS binary_log_file, MIN(primary_instance.binary_log_pos) AS binary_log_pos, @@ -183,17 +183,6 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna ), 0 ) AS count_valid_semi_sync_replicas, - MIN( - primary_instance.mariadb_gtid - ) AS is_mariadb_gtid, - SUM(replica_instance.mariadb_gtid) AS count_mariadb_gtid_replicas, - IFNULL( - SUM( - replica_instance.last_checked <= replica_instance.last_seen - AND replica_instance.mariadb_gtid != 0 - ), - 0 - ) AS count_valid_mariadb_gtid_replicas, IFNULL( SUM( replica_instance.log_bin @@ -244,7 +233,8 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna COUNT( DISTINCT case when replica_instance.log_bin AND replica_instance.log_replica_updates then replica_instance.major_version else NULL end - ) AS count_distinct_logging_major_versions + ) AS count_distinct_logging_major_versions, + primary_instance.is_disk_stalled != 0 AS is_disk_stalled FROM vitess_tablet JOIN vitess_keyspace ON ( @@ -322,7 +312,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna a.AnalyzedInstancePrimaryAlias = topoproto.TabletAliasString(primaryTablet.Alias) a.AnalyzedInstanceBinlogCoordinates = BinlogCoordinates{ LogFile: m.GetString("binary_log_file"), - LogPos: m.GetUint32("binary_log_pos"), + LogPos: m.GetUint64("binary_log_pos"), Type: BinaryLog, } isStaleBinlogCoordinates := m.GetBool("is_stale_binlog_coordinates") @@ -339,8 +329,6 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna countValidOracleGTIDReplicas := m.GetUint("count_valid_oracle_gtid_replicas") a.OracleGTIDImmediateTopology = countValidOracleGTIDReplicas == a.CountValidReplicas && a.CountValidReplicas > 0 - countValidMariaDBGTIDReplicas := m.GetUint("count_valid_mariadb_gtid_replicas") - a.MariaDBGTIDImmediateTopology = countValidMariaDBGTIDReplicas == a.CountValidReplicas && a.CountValidReplicas > 0 countValidBinlogServerReplicas := m.GetUint("count_valid_binlog_server_replicas") a.BinlogServerImmediateTopology = countValidBinlogServerReplicas == a.CountValidReplicas && a.CountValidReplicas > 0 a.SemiSyncPrimaryEnabled = m.GetBool("semi_sync_primary_enabled") @@ -367,6 +355,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna a.HeartbeatInterval = m.GetFloat64("heartbeat_interval") a.IsReadOnly = m.GetUint("read_only") == 1 + a.IsDiskStalled = m.GetBool("is_disk_stalled") if !a.LastCheckValid { analysisMessage := fmt.Sprintf("analysis: Alias: %+v, Keyspace: %+v, Shard: %+v, IsPrimary: %+v, LastCheckValid: %+v, LastCheckPartialSuccess: %+v, CountReplicas: %+v, CountValidReplicas: %+v, CountValidReplicatingReplicas: %+v, CountLaggingReplicas: %+v, CountDelayedReplicas: %+v", @@ -388,7 +377,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna log.Errorf("ignoring keyspace %v because no durability_policy is set. Please set it using SetKeyspaceDurabilityPolicy", a.AnalyzedKeyspace) return nil } - durability, err := reparentutil.GetDurabilityPolicy(durabilityPolicy) + durability, err := policy.GetDurabilityPolicy(durabilityPolicy) if err != nil { log.Errorf("can't get the durability policy %v - %v. Skipping keyspace - %v.", durabilityPolicy, err, a.AnalyzedKeyspace) return nil @@ -414,6 +403,10 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna } else if isInvalid { a.Analysis = InvalidReplica a.Description = "VTOrc hasn't been able to reach the replica even once since restart/shutdown" + } else if a.IsClusterPrimary && !a.LastCheckValid && a.IsDiskStalled { + a.Analysis = PrimaryDiskStalled + a.Description = "Primary has a stalled disk" + ca.hasClusterwideAction = true } else if a.IsClusterPrimary && !a.LastCheckValid && a.CountReplicas == 0 { a.Analysis = DeadPrimaryWithoutReplicas a.Description = "Primary cannot be reached by vtorc and has no replica" @@ -443,11 +436,11 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna a.Analysis = PrimaryIsReadOnly a.Description = "Primary is read-only" // - } else if a.IsClusterPrimary && reparentutil.SemiSyncAckers(ca.durability, tablet) != 0 && !a.SemiSyncPrimaryEnabled { + } else if a.IsClusterPrimary && policy.SemiSyncAckers(ca.durability, tablet) != 0 && !a.SemiSyncPrimaryEnabled { a.Analysis = PrimarySemiSyncMustBeSet a.Description = "Primary semi-sync must be set" // - } else if a.IsClusterPrimary && reparentutil.SemiSyncAckers(ca.durability, tablet) == 0 && a.SemiSyncPrimaryEnabled { + } else if a.IsClusterPrimary && policy.SemiSyncAckers(ca.durability, tablet) == 0 && a.SemiSyncPrimaryEnabled { a.Analysis = PrimarySemiSyncMustNotBeSet a.Description = "Primary semi-sync must not be set" // @@ -485,11 +478,11 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna a.Analysis = ReplicationStopped a.Description = "Replication is stopped" // - } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && reparentutil.IsReplicaSemiSync(ca.durability, primaryTablet, tablet) && !a.SemiSyncReplicaEnabled { + } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && policy.IsReplicaSemiSync(ca.durability, primaryTablet, tablet) && !a.SemiSyncReplicaEnabled { a.Analysis = ReplicaSemiSyncMustBeSet a.Description = "Replica semi-sync must be set" // - } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && !reparentutil.IsReplicaSemiSync(ca.durability, primaryTablet, tablet) && a.SemiSyncReplicaEnabled { + } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && !policy.IsReplicaSemiSync(ca.durability, primaryTablet, tablet) && a.SemiSyncReplicaEnabled { a.Analysis = ReplicaSemiSyncMustNotBeSet a.Description = "Replica semi-sync must not be set" // @@ -541,7 +534,6 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna } if a.IsPrimary && a.CountReplicas > 1 && !a.OracleGTIDImmediateTopology && - !a.MariaDBGTIDImmediateTopology && !a.BinlogServerImmediateTopology { a.StructureAnalysis = append(a.StructureAnalysis, NoFailoverSupportStructureWarning) } diff --git a/go/vt/vtorc/inst/analysis_dao_test.go b/go/vt/vtorc/inst/analysis_dao_test.go index c061d54ebb3..baa1121b776 100644 --- a/go/vt/vtorc/inst/analysis_dao_test.go +++ b/go/vt/vtorc/inst/analysis_dao_test.go @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/vt/external/golib/sqlutils" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/db" "vitess.io/vitess/go/vt/vtorc/test" ) @@ -33,10 +34,10 @@ var ( // The initialSQL is a set of insert commands copied from a dump of an actual running VTOrc instances. The relevant insert commands are here. // This is a dump taken from a test running 4 tablets, zone1-101 is the primary, zone1-100 is a replica, zone1-112 is a rdonly and zone2-200 is a cross-cell replica. initialSQL = []string{ - `INSERT INTO database_instance VALUES('zone1-0000000112','localhost',6747,'2022-12-28 07:26:04','2022-12-28 07:26:04',213696377,'8.0.31','ROW',1,1,'vt-0000000112-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,0,'vt-0000000112-relay-bin.000002',15815,0,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-9240-92a06c3be3c2','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10816929,0,0,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-9240-92a06c3be3c2',1,1,'',1000000000000000000,1,0,0,0);`, - `INSERT INTO database_instance VALUES('zone1-0000000100','localhost',6711,'2022-12-28 07:26:04','2022-12-28 07:26:04',1094500338,'8.0.31','ROW',1,1,'vt-0000000100-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,0,'vt-0000000100-relay-bin.000002',15815,0,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-acf8-d6b0ef9f4eaa','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10103920,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-acf8-d6b0ef9f4eaa',1,1,'',1000000000000000000,1,0,1,0);`, - `INSERT INTO database_instance VALUES('zone1-0000000101','localhost',6714,'2022-12-28 07:26:04','2022-12-28 07:26:04',390954723,'8.0.31','ROW',1,1,'vt-0000000101-bin.000001',15583,'',0,0,0,0,0,'',0,'',0,NULL,NULL,0,'','',0,0,'',0,0,0,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a4cc4-8680-11ed-a104-47706090afbd','2022-12-28 07:26:04','',0,0,0,'Homebrew','8.0','FULL',11366095,1,1,'ON',1,'','','729a4cc4-8680-11ed-a104-47706090afbd',-1,-1,'',1000000000000000000,1,1,0,2);`, - `INSERT INTO database_instance VALUES('zone2-0000000200','localhost',6756,'2022-12-28 07:26:05','2022-12-28 07:26:05',444286571,'8.0.31','ROW',1,1,'vt-0000000200-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,0,'vt-0000000200-relay-bin.000002',15815,0,1,0,'zone2','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a497c-8680-11ed-8ad4-3f51d747db75','2022-12-28 07:26:05','',1,0,0,'Homebrew','8.0','FULL',10443112,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a497c-8680-11ed-8ad4-3f51d747db75',1,1,'',1000000000000000000,1,0,1,0);`, + `INSERT INTO database_instance VALUES('zone1-0000000112','localhost',6747,'2022-12-28 07:26:04','2022-12-28 07:26:04',213696377,'8.0.31','ROW',1,1,'vt-0000000112-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000112-relay-bin.000002',15815,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-9240-92a06c3be3c2','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10816929,0,0,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-9240-92a06c3be3c2',1,1,'',1000000000000000000,1,0,0,0,false);`, + `INSERT INTO database_instance VALUES('zone1-0000000100','localhost',6711,'2022-12-28 07:26:04','2022-12-28 07:26:04',1094500338,'8.0.31','ROW',1,1,'vt-0000000100-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000100-relay-bin.000002',15815,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-acf8-d6b0ef9f4eaa','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10103920,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-acf8-d6b0ef9f4eaa',1,1,'',1000000000000000000,1,0,1,0,false);`, + `INSERT INTO database_instance VALUES('zone1-0000000101','localhost',6714,'2022-12-28 07:26:04','2022-12-28 07:26:04',390954723,'8.0.31','ROW',1,1,'vt-0000000101-bin.000001',15583,'',0,0,0,0,0,'',0,'',0,NULL,NULL,0,'','',0,'',0,0,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a4cc4-8680-11ed-a104-47706090afbd','2022-12-28 07:26:04','',0,0,0,'Homebrew','8.0','FULL',11366095,1,1,'ON',1,'','','729a4cc4-8680-11ed-a104-47706090afbd',-1,-1,'',1000000000000000000,1,1,0,2,false);`, + `INSERT INTO database_instance VALUES('zone2-0000000200','localhost',6756,'2022-12-28 07:26:05','2022-12-28 07:26:05',444286571,'8.0.31','ROW',1,1,'vt-0000000200-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000200-relay-bin.000002',15815,1,0,'zone2','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a497c-8680-11ed-8ad4-3f51d747db75','2022-12-28 07:26:05','',1,0,0,'Homebrew','8.0','FULL',10443112,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a497c-8680-11ed-8ad4-3f51d747db75',1,1,'',1000000000000000000,1,0,1,0,false);`, `INSERT INTO vitess_tablet VALUES('zone1-0000000100','localhost',6711,'ks','0','zone1',2,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3130307d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363731307d20706f72745f6d61703a7b6b65793a227674222076616c75653a363730397d206b657973706163653a226b73222073686172643a22302220747970653a5245504c494341206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363731312064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, `INSERT INTO vitess_tablet VALUES('zone1-0000000101','localhost',6714,'ks','0','zone1',1,'2022-12-28 07:23:25.129898+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3130317d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363731337d20706f72745f6d61703a7b6b65793a227674222076616c75653a363731327d206b657973706163653a226b73222073686172643a22302220747970653a5052494d415259206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a36373134207072696d6172795f7465726d5f73746172745f74696d653a7b7365636f6e64733a31363732323132323035206e616e6f7365636f6e64733a3132393839383030307d2064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, `INSERT INTO vitess_tablet VALUES('zone1-0000000112','localhost',6747,'ks','0','zone1',3,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3131327d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363734367d20706f72745f6d61703a7b6b65793a227674222076616c75653a363734357d206b657973706163653a226b73222073686172643a22302220747970653a52444f4e4c59206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363734372064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, @@ -70,7 +71,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, }}, keyspaceWanted: "ks", @@ -89,14 +90,14 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlPort: 6709, }, ShardPrimaryTermTimestamp: "2022-12-28 07:23:25.129898+00:00", - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, }}, keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimaryTabletDeleted, }, { - name: "DeadPrimary", + name: "StalledDiskPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, @@ -113,6 +114,29 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CountValidReplicas: 4, CountValidReplicatingReplicas: 0, IsPrimary: 1, + IsStalledDisk: 1, + }}, + keyspaceWanted: "ks", + shardWanted: "0", + codeWanted: PrimaryDiskStalled, + }, { + name: "DeadPrimary", + info: []*test.InfoForRecoveryAnalysis{{ + TabletInfo: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Hostname: "localhost", + Keyspace: "ks", + Shard: "0", + Type: topodatapb.TabletType_PRIMARY, + MysqlHostname: "localhost", + MysqlPort: 6709, + }, + DurabilityPolicy: policy.DurabilityNone, + LastCheckValid: 0, + CountReplicas: 4, + CountValidReplicas: 4, + CountValidReplicatingReplicas: 0, + IsPrimary: 1, }}, keyspaceWanted: "ks", shardWanted: "0", @@ -129,7 +153,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 0, CountReplicas: 0, IsPrimary: 1, @@ -149,7 +173,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 0, CountReplicas: 3, IsPrimary: 1, @@ -169,7 +193,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 0, CountReplicas: 4, CountValidReplicas: 2, @@ -191,7 +215,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -212,7 +236,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -234,7 +258,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -256,7 +280,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -278,7 +302,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -315,7 +339,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -333,7 +357,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, }, @@ -355,7 +379,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -373,7 +397,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 102}, }, @@ -395,7 +419,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -413,7 +437,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, }, @@ -436,7 +460,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -454,7 +478,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, }, @@ -477,7 +501,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -495,7 +519,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, }, @@ -520,7 +544,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -542,7 +566,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, }, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, LastCheckValid: 1, ReadOnly: 1, SemiSyncReplicaEnabled: 0, @@ -562,7 +586,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -583,7 +607,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, ReadOnly: 1, SemiSyncReplicaEnabled: 1, @@ -605,7 +629,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { }, // Snapshot Keyspace KeyspaceType: 1, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, }}, keyspaceWanted: "ks", @@ -643,7 +667,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -663,7 +687,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlPort: 6709, }, IsInvalid: 1, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, }}, keyspaceWanted: "ks", shardWanted: "0", @@ -680,7 +704,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, IsInvalid: 1, }, { TabletInfo: &topodatapb.Tablet{ @@ -722,7 +746,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, IsInvalid: 1, }}, keyspaceWanted: "ks", @@ -740,7 +764,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -758,7 +782,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, ErrantGTID: "some errant GTID", PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, @@ -781,7 +805,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6708, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, CountReplicas: 4, CountValidReplicas: 4, @@ -799,7 +823,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, ErrantGTID: "some errant GTID", PrimaryTabletInfo: &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, diff --git a/go/vt/vtorc/inst/binlog.go b/go/vt/vtorc/inst/binlog.go index 9c115e4e457..b4abf34ac7e 100644 --- a/go/vt/vtorc/inst/binlog.go +++ b/go/vt/vtorc/inst/binlog.go @@ -40,22 +40,23 @@ const ( // BinlogCoordinates described binary log coordinates in the form of log file & log position. type BinlogCoordinates struct { LogFile string - LogPos uint32 + LogPos uint64 Type BinlogType } -// ParseInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306 +// ParseBinlogCoordinates will parse a string representation such as "mysql-bin.000001:12345" +// into a BinlogCoordinates struct. func ParseBinlogCoordinates(logFileLogPos string) (*BinlogCoordinates, error) { tokens := strings.SplitN(logFileLogPos, ":", 2) if len(tokens) != 2 { return nil, fmt.Errorf("ParseBinlogCoordinates: Cannot parse BinlogCoordinates from %s. Expected format is file:pos", logFileLogPos) } - logPos, err := strconv.ParseUint(tokens[1], 10, 32) + logPos, err := strconv.ParseUint(tokens[1], 10, 64) if err != nil { return nil, fmt.Errorf("ParseBinlogCoordinates: invalid pos: %s", tokens[1]) } - return &BinlogCoordinates{LogFile: tokens[0], LogPos: uint32(logPos)}, nil + return &BinlogCoordinates{LogFile: tokens[0], LogPos: logPos}, nil } // DisplayString returns a user-friendly string representation of these coordinates @@ -177,6 +178,6 @@ func (binlogCoordinates *BinlogCoordinates) ExtractDetachedCoordinates() (isDeta } detachedCoordinates.LogFile = detachedCoordinatesSubmatch[1] logPos, _ := strconv.ParseUint(detachedCoordinatesSubmatch[2], 10, 32) - detachedCoordinates.LogPos = uint32(logPos) + detachedCoordinates.LogPos = logPos return true, detachedCoordinates } diff --git a/go/vt/vtorc/inst/binlog_test.go b/go/vt/vtorc/inst/binlog_test.go index bc0110e981c..1f73f3c0029 100644 --- a/go/vt/vtorc/inst/binlog_test.go +++ b/go/vt/vtorc/inst/binlog_test.go @@ -41,7 +41,7 @@ func TestPreviousFileCoordinates(t *testing.T) { require.NoError(t, err) require.Equal(t, previous.LogFile, "mysql-bin.000009") - require.Equal(t, previous.LogPos, uint32(0)) + require.Equal(t, previous.LogPos, uint64(0)) } func TestNextFileCoordinates(t *testing.T) { @@ -49,7 +49,7 @@ func TestNextFileCoordinates(t *testing.T) { require.NoError(t, err) require.Equal(t, next.LogFile, "mysql-bin.000011") - require.Equal(t, next.LogPos, uint32(0)) + require.Equal(t, next.LogPos, uint64(0)) } func TestBinlogCoordinates(t *testing.T) { diff --git a/go/vt/vtorc/inst/instance.go b/go/vt/vtorc/inst/instance.go index 36f47b7ab0b..b7b097bb14d 100644 --- a/go/vt/vtorc/inst/instance.go +++ b/go/vt/vtorc/inst/instance.go @@ -56,8 +56,6 @@ type Instance struct { GTIDMode string SupportsOracleGTID bool UsingOracleGTID bool - UsingMariaDBGTID bool - UsingPseudoGTID bool // Legacy. Always 'false' ReadBinlogCoordinates BinlogCoordinates ExecBinlogCoordinates BinlogCoordinates IsDetached bool @@ -93,6 +91,7 @@ type Instance struct { IsUpToDate bool IsRecentlyChecked bool SecondsSinceLastSeen sql.NullInt64 + StalledDisk bool AllowTLS bool @@ -134,11 +133,6 @@ func (instance *Instance) MajorVersionString() string { return strings.Join(instance.MajorVersion(), ".") } -// IsMariaDB checks whether this is any version of MariaDB -func (instance *Instance) IsMariaDB() bool { - return strings.Contains(instance.Version, "MariaDB") -} - // IsPercona checks whether this is any version of Percona Server func (instance *Instance) IsPercona() bool { return strings.Contains(instance.VersionComment, "Percona") @@ -151,9 +145,6 @@ func (instance *Instance) IsBinlogServer() bool { // IsOracleMySQL checks whether this is an Oracle MySQL distribution func (instance *Instance) IsOracleMySQL() bool { - if instance.IsMariaDB() { - return false - } if instance.IsPercona() { return false } @@ -170,8 +161,6 @@ func (instance *Instance) applyFlavorName() { } if instance.IsOracleMySQL() { instance.FlavorName = "MySQL" - } else if instance.IsMariaDB() { - instance.FlavorName = "MariaDB" } else if instance.IsPercona() { instance.FlavorName = "Percona" } else { @@ -220,7 +209,7 @@ func (instance *Instance) SQLThreadUpToDate() bool { return instance.ReadBinlogCoordinates.Equals(&instance.ExecBinlogCoordinates) } -// UsingGTID returns true when this replica is currently replicating via GTID (either Oracle or MariaDB) +// UsingGTID returns true when this replica is currently replicating via GTID func (instance *Instance) UsingGTID() bool { - return instance.UsingOracleGTID || instance.UsingMariaDBGTID + return instance.UsingOracleGTID } diff --git a/go/vt/vtorc/inst/instance_dao.go b/go/vt/vtorc/inst/instance_dao.go index d1421dbc91d..9e35e6e3e0b 100644 --- a/go/vt/vtorc/inst/instance_dao.go +++ b/go/vt/vtorc/inst/instance_dao.go @@ -175,6 +175,7 @@ func ReadTopologyInstanceBufferable(tabletAlias string, latency *stopwatch.Named var tablet *topodatapb.Tablet var fs *replicationdatapb.FullStatus readingStartTime := time.Now() + stalledDisk := false instance := NewInstance() instanceFound := false partialSuccess := false @@ -207,6 +208,10 @@ func ReadTopologyInstanceBufferable(tabletAlias string, latency *stopwatch.Named if err != nil { goto Cleanup } + if config.GetStalledDiskPrimaryRecovery() && fs.DiskStalled { + stalledDisk = true + goto Cleanup + } partialSuccess = true // We at least managed to read something from the server. instance.Hostname = tablet.MysqlHostname @@ -291,7 +296,6 @@ func ReadTopologyInstanceBufferable(tabletAlias string, latency *stopwatch.Named instance.SQLDelay = fs.ReplicationStatus.SqlDelay instance.UsingOracleGTID = fs.ReplicationStatus.AutoPosition - instance.UsingMariaDBGTID = fs.ReplicationStatus.UsingGtid instance.SourceUUID = fs.ReplicationStatus.SourceUuid instance.HasReplicationFilters = fs.ReplicationStatus.HasReplicationFilters @@ -382,9 +386,10 @@ Cleanup: // Something is wrong, could be network-wise. Record that we // tried to check the instance. last_attempted_check is also - // updated on success by writeInstance. + // updated on success by writeInstance. If the reason is a + // stalled disk, we can record that as well. latency.Start("backend") - _ = UpdateInstanceLastChecked(tabletAlias, partialSuccess) + _ = UpdateInstanceLastChecked(tabletAlias, partialSuccess, stalledDisk) latency.Stop("backend") return nil, err } @@ -548,16 +553,15 @@ func readInstanceRow(m sqlutils.RowMap) *Instance { instance.GTIDMode = m.GetString("gtid_mode") instance.GtidPurged = m.GetString("gtid_purged") instance.GtidErrant = m.GetString("gtid_errant") - instance.UsingMariaDBGTID = m.GetBool("mariadb_gtid") instance.SelfBinlogCoordinates.LogFile = m.GetString("binary_log_file") - instance.SelfBinlogCoordinates.LogPos = m.GetUint32("binary_log_pos") + instance.SelfBinlogCoordinates.LogPos = m.GetUint64("binary_log_pos") instance.ReadBinlogCoordinates.LogFile = m.GetString("source_log_file") - instance.ReadBinlogCoordinates.LogPos = m.GetUint32("read_source_log_pos") + instance.ReadBinlogCoordinates.LogPos = m.GetUint64("read_source_log_pos") instance.ExecBinlogCoordinates.LogFile = m.GetString("relay_source_log_file") - instance.ExecBinlogCoordinates.LogPos = m.GetUint32("exec_source_log_pos") + instance.ExecBinlogCoordinates.LogPos = m.GetUint64("exec_source_log_pos") instance.IsDetached, _ = instance.ExecBinlogCoordinates.ExtractDetachedCoordinates() instance.RelaylogCoordinates.LogFile = m.GetString("relay_log_file") - instance.RelaylogCoordinates.LogPos = m.GetUint32("relay_log_pos") + instance.RelaylogCoordinates.LogPos = m.GetUint64("relay_log_pos") instance.RelaylogCoordinates.Type = RelayLog instance.LastSQLError = m.GetString("last_sql_error") instance.LastIOError = m.GetString("last_io_error") @@ -849,8 +853,6 @@ func mkInsertForInstances(instances []*Instance, instanceWasActuallyFound bool, "gtid_mode", "gtid_purged", "gtid_errant", - "mariadb_gtid", - "pseudo_gtid", "source_log_file", "read_source_log_pos", "relay_source_log_file", @@ -878,6 +880,7 @@ func mkInsertForInstances(instances []*Instance, instanceWasActuallyFound bool, "semi_sync_primary_clients", "semi_sync_replica_status", "last_discovery_latency", + "is_disk_stalled", } values := make([]string, len(columns)) @@ -930,8 +933,6 @@ func mkInsertForInstances(instances []*Instance, instanceWasActuallyFound bool, args = append(args, instance.GTIDMode) args = append(args, instance.GtidPurged) args = append(args, instance.GtidErrant) - args = append(args, instance.UsingMariaDBGTID) - args = append(args, instance.UsingPseudoGTID) args = append(args, instance.ReadBinlogCoordinates.LogFile) args = append(args, instance.ReadBinlogCoordinates.LogPos) args = append(args, instance.ExecBinlogCoordinates.LogFile) @@ -959,6 +960,7 @@ func mkInsertForInstances(instances []*Instance, instanceWasActuallyFound bool, args = append(args, instance.SemiSyncPrimaryClients) args = append(args, instance.SemiSyncReplicaStatus) args = append(args, instance.LastDiscoveryLatency.Nanoseconds()) + args = append(args, instance.StalledDisk) } sql, err := mkInsert("database_instance", columns, values, len(instances), insertIgnore) @@ -1004,16 +1006,18 @@ func WriteInstance(instance *Instance, instanceWasActuallyFound bool, lastError // UpdateInstanceLastChecked updates the last_check timestamp in the vtorc backed database // for a given instance -func UpdateInstanceLastChecked(tabletAlias string, partialSuccess bool) error { +func UpdateInstanceLastChecked(tabletAlias string, partialSuccess bool, stalledDisk bool) error { writeFunc := func() error { _, err := db.ExecVTOrc(`UPDATE database_instance SET last_checked = DATETIME('now'), - last_check_partial_success = ? + last_check_partial_success = ?, + is_disk_stalled = ? WHERE alias = ? `, partialSuccess, + stalledDisk, tabletAlias, ) if err != nil { diff --git a/go/vt/vtorc/inst/instance_dao_test.go b/go/vt/vtorc/inst/instance_dao_test.go index cc3217442ed..c3b99455741 100644 --- a/go/vt/vtorc/inst/instance_dao_test.go +++ b/go/vt/vtorc/inst/instance_dao_test.go @@ -63,14 +63,14 @@ func TestMkInsertSingle(t *testing.T) { (alias, hostname, port, last_checked, last_attempted_check, last_check_partial_success, server_id, server_uuid, version, major_version, version_comment, binlog_server, read_only, binlog_format, binlog_row_image, log_bin, log_replica_updates, binary_log_file, binary_log_pos, source_host, source_port, replica_net_timeout, heartbeat_interval, - replica_sql_running, replica_io_running, replication_sql_thread_state, replication_io_thread_state, has_replication_filters, supports_oracle_gtid, oracle_gtid, source_uuid, ancestry_uuid, executed_gtid_set, gtid_mode, gtid_purged, gtid_errant, mariadb_gtid, pseudo_gtid, - source_log_file, read_source_log_pos, relay_source_log_file, exec_source_log_pos, relay_log_file, relay_log_pos, last_sql_error, last_io_error, replication_lag_seconds, replica_lag_seconds, sql_delay, data_center, region, physical_environment, replication_depth, is_co_primary, has_replication_credentials, allow_tls, semi_sync_enforced, semi_sync_primary_enabled, semi_sync_primary_timeout, semi_sync_primary_wait_for_replica_count, semi_sync_replica_enabled, semi_sync_primary_status, semi_sync_primary_clients, semi_sync_replica_status, last_discovery_latency, last_seen) + replica_sql_running, replica_io_running, replication_sql_thread_state, replication_io_thread_state, has_replication_filters, supports_oracle_gtid, oracle_gtid, source_uuid, ancestry_uuid, executed_gtid_set, gtid_mode, gtid_purged, gtid_errant, + source_log_file, read_source_log_pos, relay_source_log_file, exec_source_log_pos, relay_log_file, relay_log_pos, last_sql_error, last_io_error, replication_lag_seconds, replica_lag_seconds, sql_delay, data_center, region, physical_environment, replication_depth, is_co_primary, has_replication_credentials, allow_tls, semi_sync_enforced, semi_sync_primary_enabled, semi_sync_primary_timeout, semi_sync_primary_wait_for_replica_count, semi_sync_replica_enabled, semi_sync_primary_status, semi_sync_primary_clients, semi_sync_replica_status, last_discovery_latency, is_disk_stalled, last_seen) VALUES - (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')) + (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')) ` a1 := `zone1-i710, i710, 3306, 710, , 5.6.7, 5.6, MySQL, false, false, STATEMENT, FULL, false, false, , 0, , 0, 0, 0, - false, false, 0, 0, false, false, false, , , , , , , false, false, , 0, mysql.000007, 10, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0,` + false, false, 0, 0, false, false, false, , , , , , , , 0, mysql.000007, 10, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0, false,` sql1, args1, err := mkInsertForInstances(instances[:1], false, true) require.NoError(t, err) @@ -86,17 +86,17 @@ func TestMkInsertThree(t *testing.T) { (alias, hostname, port, last_checked, last_attempted_check, last_check_partial_success, server_id, server_uuid, version, major_version, version_comment, binlog_server, read_only, binlog_format, binlog_row_image, log_bin, log_replica_updates, binary_log_file, binary_log_pos, source_host, source_port, replica_net_timeout, heartbeat_interval, - replica_sql_running, replica_io_running, replication_sql_thread_state, replication_io_thread_state, has_replication_filters, supports_oracle_gtid, oracle_gtid, source_uuid, ancestry_uuid, executed_gtid_set, gtid_mode, gtid_purged, gtid_errant, mariadb_gtid, pseudo_gtid, - source_log_file, read_source_log_pos, relay_source_log_file, exec_source_log_pos, relay_log_file, relay_log_pos, last_sql_error, last_io_error, replication_lag_seconds, replica_lag_seconds, sql_delay, data_center, region, physical_environment, replication_depth, is_co_primary, has_replication_credentials, allow_tls, semi_sync_enforced, semi_sync_primary_enabled, semi_sync_primary_timeout, semi_sync_primary_wait_for_replica_count, semi_sync_replica_enabled, semi_sync_primary_status, semi_sync_primary_clients, semi_sync_replica_status, last_discovery_latency, last_seen) + replica_sql_running, replica_io_running, replication_sql_thread_state, replication_io_thread_state, has_replication_filters, supports_oracle_gtid, oracle_gtid, source_uuid, ancestry_uuid, executed_gtid_set, gtid_mode, gtid_purged, gtid_errant, + source_log_file, read_source_log_pos, relay_source_log_file, exec_source_log_pos, relay_log_file, relay_log_pos, last_sql_error, last_io_error, replication_lag_seconds, replica_lag_seconds, sql_delay, data_center, region, physical_environment, replication_depth, is_co_primary, has_replication_credentials, allow_tls, semi_sync_enforced, semi_sync_primary_enabled, semi_sync_primary_timeout, semi_sync_primary_wait_for_replica_count, semi_sync_replica_enabled, semi_sync_primary_status, semi_sync_primary_clients, semi_sync_replica_status, last_discovery_latency, is_disk_stalled, last_seen) VALUES - (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')), - (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')), - (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')) + (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')), + (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')), + (?, ?, ?, DATETIME('now'), DATETIME('now'), 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now')) ` a3 := ` - zone1-i710, i710, 3306, 710, , 5.6.7, 5.6, MySQL, false, false, STATEMENT, FULL, false, false, , 0, , 0, 0, 0, false, false, 0, 0, false, false, false, , , , , , , false, false, , 0, mysql.000007, 10, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0, - zone1-i720, i720, 3306, 720, , 5.6.7, 5.6, MySQL, false, false, STATEMENT, FULL, false, false, , 0, , 0, 0, 0, false, false, 0, 0, false, false, false, , , , , , , false, false, , 0, mysql.000007, 20, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0, - zone1-i730, i730, 3306, 730, , 5.6.7, 5.6, MySQL, false, false, STATEMENT, FULL, false, false, , 0, , 0, 0, 0, false, false, 0, 0, false, false, false, , , , , , , false, false, , 0, mysql.000007, 30, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0, + zone1-i710, i710, 3306, 710, , 5.6.7, 5.6, MySQL, false, false, STATEMENT, FULL, false, false, , 0, , 0, 0, 0, false, false, 0, 0, false, false, false, , , , , , , , 0, mysql.000007, 10, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0, false, + zone1-i720, i720, 3306, 720, , 5.6.7, 5.6, MySQL, false, false, STATEMENT, FULL, false, false, , 0, , 0, 0, 0, false, false, 0, 0, false, false, false, , , , , , , , 0, mysql.000007, 20, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0, false, + zone1-i730, i730, 3306, 730, , 5.6.7, 5.6, MySQL, false, false, STATEMENT, FULL, false, false, , 0, , 0, 0, 0, false, false, 0, 0, false, false, false, , , , , , , , 0, mysql.000007, 30, , 0, , , {0 false}, {0 false}, 0, , , , 0, false, false, false, false, false, 0, 0, false, false, 0, false, 0, false, ` sql3, args3, err := mkInsertForInstances(instances[:3], true, true) @@ -483,9 +483,9 @@ func TestReadOutdatedInstanceKeys(t *testing.T) { tabletAliases, err := ReadOutdatedInstanceKeys() - errInDataCollection := db.QueryVTOrcRowsMap(`select alias, -last_checked, -last_attempted_check, + errInDataCollection := db.QueryVTOrcRowsMap(`select alias, +last_checked, +last_attempted_check, ROUND((JULIANDAY(DATETIME('now')) - JULIANDAY(last_checked)) * 86400) AS difference, last_attempted_check <= last_checked as use1, last_checked < DATETIME('now', '-1500 second') as is_outdated1, @@ -507,22 +507,32 @@ func TestUpdateInstanceLastChecked(t *testing.T) { name string tabletAlias string partialSuccess bool + stalledDisk bool conditionToCheck string }{ { name: "Verify updated last checked", tabletAlias: "zone1-0000000100", partialSuccess: false, - conditionToCheck: "last_checked >= DATETIME('now', '-30 second') and last_check_partial_success = false", + stalledDisk: false, + conditionToCheck: "last_checked >= DATETIME('now', '-30 second') and last_check_partial_success = false and is_disk_stalled = false", }, { name: "Verify partial success", tabletAlias: "zone1-0000000100", partialSuccess: true, - conditionToCheck: "last_checked >= DATETIME('now', '-30 second') and last_check_partial_success = true", + stalledDisk: false, + conditionToCheck: "last_checked >= datetime('now', '-30 second') and last_check_partial_success = true and is_disk_stalled = false", + }, { + name: "Verify stalled disk", + tabletAlias: "zone1-0000000100", + partialSuccess: false, + stalledDisk: true, + conditionToCheck: "last_checked >= DATETIME('now', '-30 second') and last_check_partial_success = false and is_disk_stalled = true", }, { name: "Verify no error on unknown tablet", tabletAlias: "unknown tablet", partialSuccess: true, + stalledDisk: true, }, } @@ -537,7 +547,7 @@ func TestUpdateInstanceLastChecked(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := UpdateInstanceLastChecked(tt.tabletAlias, tt.partialSuccess) + err := UpdateInstanceLastChecked(tt.tabletAlias, tt.partialSuccess, tt.stalledDisk) require.NoError(t, err) if tt.conditionToCheck != "" { diff --git a/go/vt/vtorc/inst/keyspace_dao.go b/go/vt/vtorc/inst/keyspace_dao.go index d764e3fc56a..4271886121e 100644 --- a/go/vt/vtorc/inst/keyspace_dao.go +++ b/go/vt/vtorc/inst/keyspace_dao.go @@ -22,7 +22,7 @@ import ( "vitess.io/vitess/go/vt/external/golib/sqlutils" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/db" ) @@ -80,10 +80,10 @@ func SaveKeyspace(keyspace *topo.KeyspaceInfo) error { } // GetDurabilityPolicy gets the durability policy for the given keyspace. -func GetDurabilityPolicy(keyspace string) (reparentutil.Durabler, error) { +func GetDurabilityPolicy(keyspace string) (policy.Durabler, error) { ki, err := ReadKeyspace(keyspace) if err != nil { return nil, err } - return reparentutil.GetDurabilityPolicy(ki.DurabilityPolicy) + return policy.GetDurabilityPolicy(ki.DurabilityPolicy) } diff --git a/go/vt/vtorc/inst/keyspace_dao_test.go b/go/vt/vtorc/inst/keyspace_dao_test.go index dda3ffaa9d2..ef2dd67379e 100644 --- a/go/vt/vtorc/inst/keyspace_dao_test.go +++ b/go/vt/vtorc/inst/keyspace_dao_test.go @@ -24,7 +24,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topotools" - "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/db" ) @@ -48,7 +48,7 @@ func TestSaveAndReadKeyspace(t *testing.T) { keyspaceName: "ks1", keyspace: &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, }, keyspaceWanted: nil, semiSyncAckersWanted: 1, @@ -72,12 +72,12 @@ func TestSaveAndReadKeyspace(t *testing.T) { keyspaceName: "ks4", keyspace: &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, BaseKeyspace: "baseKeyspace", }, keyspaceWanted: &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, }, semiSyncAckersWanted: 0, }, { @@ -120,7 +120,7 @@ func TestSaveAndReadKeyspace(t *testing.T) { return } require.NoError(t, err) - require.EqualValues(t, tt.semiSyncAckersWanted, reparentutil.SemiSyncAckers(durabilityPolicy, nil)) + require.EqualValues(t, tt.semiSyncAckersWanted, policy.SemiSyncAckers(durabilityPolicy, nil)) }) } } diff --git a/go/vt/vtorc/logic/keyspace_shard_discovery.go b/go/vt/vtorc/logic/keyspace_shard_discovery.go index b1e93fe2a01..8115e614418 100644 --- a/go/vt/vtorc/logic/keyspace_shard_discovery.go +++ b/go/vt/vtorc/logic/keyspace_shard_discovery.go @@ -18,10 +18,10 @@ package logic import ( "context" - "sort" - "strings" "sync" + "golang.org/x/exp/maps" + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/topo" @@ -29,40 +29,23 @@ import ( ) // RefreshAllKeyspacesAndShards reloads the keyspace and shard information for the keyspaces that vtorc is concerned with. -func RefreshAllKeyspacesAndShards() { +func RefreshAllKeyspacesAndShards(ctx context.Context) error { var keyspaces []string - if len(clustersToWatch) == 0 { // all known keyspaces - ctx, cancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) + if len(shardsToWatch) == 0 { // all known keyspaces + ctx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) defer cancel() var err error // Get all the keyspaces keyspaces, err = ts.GetKeyspaces(ctx) if err != nil { - log.Error(err) - return + return err } } else { - // Parse input and build list of keyspaces - for _, ks := range clustersToWatch { - if strings.Contains(ks, "/") { - // This is a keyspace/shard specification - input := strings.Split(ks, "/") - keyspaces = append(keyspaces, input[0]) - } else { - // Assume this is a keyspace - keyspaces = append(keyspaces, ks) - } - } - if len(keyspaces) == 0 { - log.Errorf("Found no keyspaces for input: %+v", clustersToWatch) - return - } + // Get keyspaces to watch from the list of known keyspaces. + keyspaces = maps.Keys(shardsToWatch) } - // Sort the list of keyspaces. - // The list can have duplicates because the input to clusters to watch may have multiple shards of the same keyspace - sort.Strings(keyspaces) - refreshCtx, refreshCancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) + refreshCtx, refreshCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) defer refreshCancel() var wg sync.WaitGroup for idx, keyspace := range keyspaces { @@ -83,6 +66,8 @@ func RefreshAllKeyspacesAndShards() { }(keyspace) } wg.Wait() + + return nil } // RefreshKeyspaceAndShard refreshes the keyspace record and shard record for the given keyspace and shard. diff --git a/go/vt/vtorc/logic/keyspace_shard_discovery_test.go b/go/vt/vtorc/logic/keyspace_shard_discovery_test.go index 097865db84a..f05295416d0 100644 --- a/go/vt/vtorc/logic/keyspace_shard_discovery_test.go +++ b/go/vt/vtorc/logic/keyspace_shard_discovery_test.go @@ -28,6 +28,7 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtctl/reparentutil/reparenttestutil" "vitess.io/vitess/go/vt/vtorc/db" "vitess.io/vitess/go/vt/vtorc/inst" @@ -36,15 +37,15 @@ import ( var ( keyspaceDurabilityNone = &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, } keyspaceDurabilitySemiSync = &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, } keyspaceDurabilityTest = &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "test", + DurabilityPolicy: policy.DurabilityTest, } keyspaceSnapshot = &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_SNAPSHOT, @@ -92,7 +93,9 @@ func TestRefreshAllKeyspaces(t *testing.T) { // Set clusters to watch to only watch ks1 and ks3 onlyKs1and3 := []string{"ks1/-80", "ks3/-80", "ks3/80-"} clustersToWatch = onlyKs1and3 - RefreshAllKeyspacesAndShards() + err := initializeShardsToWatch() + require.NoError(t, err) + require.NoError(t, RefreshAllKeyspacesAndShards(context.Background())) // Verify that we only have ks1 and ks3 in vtorc's db. verifyKeyspaceInfo(t, "ks1", keyspaceDurabilityNone, "") @@ -105,9 +108,11 @@ func TestRefreshAllKeyspaces(t *testing.T) { // Set clusters to watch to watch all keyspaces clustersToWatch = nil + err = initializeShardsToWatch() + require.NoError(t, err) // Change the durability policy of ks1 - reparenttestutil.SetKeyspaceDurability(ctx, t, ts, "ks1", "semi_sync") - RefreshAllKeyspacesAndShards() + reparenttestutil.SetKeyspaceDurability(ctx, t, ts, "ks1", policy.DurabilitySemiSync) + require.NoError(t, RefreshAllKeyspacesAndShards(context.Background())) // Verify that all the keyspaces are correctly reloaded verifyKeyspaceInfo(t, "ks1", keyspaceDurabilitySemiSync, "") @@ -118,7 +123,6 @@ func TestRefreshAllKeyspaces(t *testing.T) { verifyPrimaryAlias(t, "ks3", "80-", "zone_ks3-0000000101", "") verifyKeyspaceInfo(t, "ks4", keyspaceDurabilityTest, "") verifyPrimaryAlias(t, "ks4", "80-", "zone_ks4-0000000101", "") - } func TestRefreshKeyspace(t *testing.T) { @@ -144,7 +148,7 @@ func TestRefreshKeyspace(t *testing.T) { keyspaceName: "ks1", keyspace: &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "semi_sync", + DurabilityPolicy: policy.DurabilitySemiSync, }, keyspaceWanted: nil, err: "", @@ -169,12 +173,12 @@ func TestRefreshKeyspace(t *testing.T) { keyspaceName: "ks4", keyspace: &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, BaseKeyspace: "baseKeyspace", }, keyspaceWanted: &topodatapb.Keyspace{ KeyspaceType: topodatapb.KeyspaceType_NORMAL, - DurabilityPolicy: "none", + DurabilityPolicy: policy.DurabilityNone, }, err: "", }, { diff --git a/go/vt/vtorc/logic/tablet_discovery.go b/go/vt/vtorc/logic/tablet_discovery.go index e62c0652e62..c5c23df0cd0 100644 --- a/go/vt/vtorc/logic/tablet_discovery.go +++ b/go/vt/vtorc/logic/tablet_discovery.go @@ -27,21 +27,20 @@ import ( "time" "github.com/spf13/pflag" - + "golang.org/x/sync/errgroup" "google.golang.org/protobuf/encoding/prototext" "google.golang.org/protobuf/proto" "vitess.io/vitess/go/vt/external/golib/sqlutils" + "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtorc/config" "vitess.io/vitess/go/vt/vtorc/db" "vitess.io/vitess/go/vt/vtorc/inst" - "vitess.io/vitess/go/vt/vtorc/process" "vitess.io/vitess/go/vt/vttablet/tmclient" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) var ( @@ -50,16 +49,83 @@ var ( clustersToWatch []string shutdownWaitTime = 30 * time.Second shardsLockCounter int32 + // shardsToWatch is a map storing the shards for a given keyspace that need to be watched. + // We store the key range for all the shards that we want to watch. + // This is populated by parsing `--clusters_to_watch` flag. + shardsToWatch map[string][]*topodatapb.KeyRange + // ErrNoPrimaryTablet is a fixed error message. ErrNoPrimaryTablet = errors.New("no primary tablet found") ) // RegisterFlags registers the flags required by VTOrc func RegisterFlags(fs *pflag.FlagSet) { - fs.StringSliceVar(&clustersToWatch, "clusters_to_watch", clustersToWatch, "Comma-separated list of keyspaces or keyspace/shards that this instance will monitor and repair. Defaults to all clusters in the topology. Example: \"ks1,ks2/-80\"") + fs.StringSliceVar(&clustersToWatch, "clusters_to_watch", clustersToWatch, "Comma-separated list of keyspaces or keyspace/keyranges that this instance will monitor and repair. Defaults to all clusters in the topology. Example: \"ks1,ks2/-80\"") fs.DurationVar(&shutdownWaitTime, "shutdown_wait_time", shutdownWaitTime, "Maximum time to wait for VTOrc to release all the locks that it is holding before shutting down on SIGTERM") } +// initializeShardsToWatch parses the --clusters_to_watch flag-value +// into a map of keyspace/shards. +func initializeShardsToWatch() error { + shardsToWatch = make(map[string][]*topodatapb.KeyRange) + if len(clustersToWatch) == 0 { + return nil + } + + for _, ks := range clustersToWatch { + if strings.Contains(ks, "/") && !strings.HasSuffix(ks, "/") { + // Validate keyspace/shard parses. + k, s, err := topoproto.ParseKeyspaceShard(ks) + if err != nil { + log.Errorf("Could not parse keyspace/shard %q: %+v", ks, err) + continue + } + if !key.IsValidKeyRange(s) { + return fmt.Errorf("invalid key range %q while parsing clusters to watch", s) + } + // Parse the shard name into key range value. + keyRanges, err := key.ParseShardingSpec(s) + if err != nil { + return fmt.Errorf("could not parse shard name %q: %+v", s, err) + } + shardsToWatch[k] = append(shardsToWatch[k], keyRanges...) + } else { + // Remove trailing slash if exists. + ks = strings.TrimSuffix(ks, "/") + // We store the entire range of key range if nothing is specified. + shardsToWatch[ks] = []*topodatapb.KeyRange{key.NewCompleteKeyRange()} + } + } + + if len(shardsToWatch) == 0 { + log.Error("No keyspace/shards to watch, watching all keyspaces") + } + return nil +} + +// shouldWatchTablet checks if the given tablet is part of the watch list. +func shouldWatchTablet(tablet *topodatapb.Tablet) bool { + // If we are watching all keyspaces, then we want to watch this tablet too. + if len(shardsToWatch) == 0 { + return true + } + shardRanges, ok := shardsToWatch[tablet.GetKeyspace()] + // If we don't have the keyspace in our map, then this tablet + // doesn't need to be watched. + if !ok { + return false + } + // Get the tablet's key range, and check if + // it is part of the shard ranges we are watching. + kr := tablet.GetKeyRange() + for _, shardRange := range shardRanges { + if key.KeyRangeContainsKeyRange(shardRange, kr) { + return true + } + } + return false +} + // OpenTabletDiscovery opens the vitess topo if enables and returns a ticker // channel for polling. func OpenTabletDiscovery() <-chan time.Time { @@ -69,100 +135,83 @@ func OpenTabletDiscovery() <-chan time.Time { if _, err := db.ExecVTOrc("DELETE FROM vitess_tablet"); err != nil { log.Error(err) } - // We refresh all information from the topo once before we start the ticks to do it on a timer. - populateAllInformation() + // Parse --clusters_to_watch into a filter. + err := initializeShardsToWatch() + if err != nil { + log.Fatalf("Error parsing --clusters-to-watch: %v", err) + } + // We refresh all information from the topo once before we start the ticks to do + // it on a timer. + ctx, cancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) + defer cancel() + if err := refreshAllInformation(ctx); err != nil { + log.Errorf("failed to initialize topo information: %+v", err) + } return time.Tick(config.GetTopoInformationRefreshDuration()) //nolint SA1015: using time.Tick leaks the underlying ticker } -// populateAllInformation initializes all the information for VTOrc to function. -func populateAllInformation() { - refreshAllInformation() - // We have completed one full discovery cycle. We should update the process health. - process.FirstDiscoveryCycleComplete.Store(true) +// getAllTablets gets all tablets from all cells using a goroutine per cell. +func getAllTablets(ctx context.Context, cells []string) []*topo.TabletInfo { + var tabletsMu sync.Mutex + tablets := make([]*topo.TabletInfo, 0) + eg, ctx := errgroup.WithContext(ctx) + for _, cell := range cells { + eg.Go(func() error { + t, err := ts.GetTabletsByCell(ctx, cell, nil) + if err != nil { + log.Errorf("Failed to load tablets from cell %s: %+v", cell, err) + return nil + } + tabletsMu.Lock() + defer tabletsMu.Unlock() + tablets = append(tablets, t...) + return nil + }) + } + _ = eg.Wait() // always nil + return tablets } // refreshAllTablets reloads the tablets from topo and discovers the ones which haven't been refreshed in a while -func refreshAllTablets() { - refreshTabletsUsing(func(tabletAlias string) { +func refreshAllTablets(ctx context.Context) error { + return refreshTabletsUsing(ctx, func(tabletAlias string) { DiscoverInstance(tabletAlias, false /* forceDiscovery */) }, false /* forceRefresh */) } -func refreshTabletsUsing(loader func(tabletAlias string), forceRefresh bool) { - if len(clustersToWatch) == 0 { // all known clusters - ctx, cancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) - defer cancel() - cells, err := ts.GetKnownCells(ctx) - if err != nil { - log.Error(err) - return - } +// refreshTabletsUsing refreshes tablets using a provided loader. +func refreshTabletsUsing(ctx context.Context, loader func(tabletAlias string), forceRefresh bool) error { + // Get all cells. + ctx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) + defer cancel() + cells, err := ts.GetKnownCells(ctx) + if err != nil { + return err + } - refreshCtx, refreshCancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) - defer refreshCancel() - var wg sync.WaitGroup - for _, cell := range cells { - wg.Add(1) - go func(cell string) { - defer wg.Done() - refreshTabletsInCell(refreshCtx, cell, loader, forceRefresh) - }(cell) - } - wg.Wait() - } else { - // Parse input and build list of keyspaces / shards - var keyspaceShards []*topo.KeyspaceShard - for _, ks := range clustersToWatch { - if strings.Contains(ks, "/") { - // This is a keyspace/shard specification - input := strings.Split(ks, "/") - keyspaceShards = append(keyspaceShards, &topo.KeyspaceShard{Keyspace: input[0], Shard: input[1]}) - } else { - // Assume this is a keyspace and find all shards in keyspace - ctx, cancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) - defer cancel() - shards, err := ts.GetShardNames(ctx, ks) - if err != nil { - // Log the errr and continue - log.Errorf("Error fetching shards for keyspace: %v", ks) - continue - } - if len(shards) == 0 { - log.Errorf("Topo has no shards for ks: %v", ks) - continue - } - for _, s := range shards { - keyspaceShards = append(keyspaceShards, &topo.KeyspaceShard{Keyspace: ks, Shard: s}) - } + // Get all tablets from all cells. + getTabletsCtx, getTabletsCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) + defer getTabletsCancel() + tablets := getAllTablets(getTabletsCtx, cells) + if len(tablets) == 0 { + log.Error("Found no tablets") + return nil + } + + // Filter tablets that should not be watched using shardsToWatch map. + matchedTablets := make([]*topo.TabletInfo, 0, len(tablets)) + func() { + for _, t := range tablets { + if shouldWatchTablet(t.Tablet) { + matchedTablets = append(matchedTablets, t) } } - if len(keyspaceShards) == 0 { - log.Errorf("Found no keyspaceShards for input: %+v", clustersToWatch) - return - } - refreshCtx, refreshCancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) - defer refreshCancel() - var wg sync.WaitGroup - for _, ks := range keyspaceShards { - wg.Add(1) - go func(ks *topo.KeyspaceShard) { - defer wg.Done() - refreshTabletsInKeyspaceShard(refreshCtx, ks.Keyspace, ks.Shard, loader, forceRefresh, nil) - }(ks) - } - wg.Wait() - } -} + }() -func refreshTabletsInCell(ctx context.Context, cell string, loader func(tabletAlias string), forceRefresh bool) { - tablets, err := ts.GetTabletsByCell(ctx, cell, &topo.GetTabletsByCellOptions{Concurrency: topo.DefaultConcurrency}) - if err != nil { - log.Errorf("Error fetching topo info for cell %v: %v", cell, err) - return - } - query := "select alias from vitess_tablet where cell = ?" - args := sqlutils.Args(cell) - refreshTablets(tablets, query, args, loader, forceRefresh, nil) + // Refresh the filtered tablets. + query := "select alias from vitess_tablet" + refreshTablets(matchedTablets, query, nil, loader, forceRefresh, nil) + return nil } // forceRefreshAllTabletsInShard is used to refresh all the tablet's information (both MySQL information and topo records) diff --git a/go/vt/vtorc/logic/tablet_discovery_test.go b/go/vt/vtorc/logic/tablet_discovery_test.go index bc9eeba1fb7..4514ef81724 100644 --- a/go/vt/vtorc/logic/tablet_discovery_test.go +++ b/go/vt/vtorc/logic/tablet_discovery_test.go @@ -19,6 +19,7 @@ package logic import ( "context" "fmt" + "strings" "sync/atomic" "testing" "time" @@ -29,6 +30,7 @@ import ( "google.golang.org/protobuf/proto" "vitess.io/vitess/go/vt/external/golib/sqlutils" + "vitess.io/vitess/go/vt/key" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/proto/vttime" "vitess.io/vitess/go/vt/topo" @@ -37,7 +39,6 @@ import ( "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" "vitess.io/vitess/go/vt/vtorc/db" "vitess.io/vitess/go/vt/vtorc/inst" - "vitess.io/vitess/go/vt/vtorc/process" ) var ( @@ -102,6 +103,221 @@ var ( } ) +func TestShouldWatchTablet(t *testing.T) { + oldClustersToWatch := clustersToWatch + defer func() { + clustersToWatch = oldClustersToWatch + shardsToWatch = nil + }() + + testCases := []struct { + in []string + tablet *topodatapb.Tablet + expectedShouldWatch bool + }{ + { + in: []string{}, + tablet: &topodatapb.Tablet{ + Keyspace: keyspace, + Shard: shard, + }, + expectedShouldWatch: true, + }, + { + in: []string{keyspace}, + tablet: &topodatapb.Tablet{ + Keyspace: keyspace, + Shard: shard, + }, + expectedShouldWatch: true, + }, + { + in: []string{keyspace + "/-"}, + tablet: &topodatapb.Tablet{ + Keyspace: keyspace, + Shard: shard, + }, + expectedShouldWatch: true, + }, + { + in: []string{keyspace + "/" + shard}, + tablet: &topodatapb.Tablet{ + Keyspace: keyspace, + Shard: shard, + }, + expectedShouldWatch: true, + }, + { + in: []string{"ks/-70", "ks/70-"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x50}, []byte{0x70}), + }, + expectedShouldWatch: true, + }, + { + in: []string{"ks/-70", "ks/70-"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x40}, []byte{0x50}), + }, + expectedShouldWatch: true, + }, + { + in: []string{"ks/-70", "ks/70-"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x70}, []byte{0x90}), + }, + expectedShouldWatch: true, + }, + { + in: []string{"ks/-70", "ks/70-"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x60}, []byte{0x90}), + }, + expectedShouldWatch: false, + }, + { + in: []string{"ks/50-70"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x50}, []byte{0x70}), + }, + expectedShouldWatch: true, + }, + { + in: []string{"ks2/-70", "ks2/70-", "unknownKs/-", "ks/-80"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x60}, []byte{0x80}), + }, + expectedShouldWatch: true, + }, + { + in: []string{"ks2/-70", "ks2/70-", "unknownKs/-", "ks/-80"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x80}, []byte{0x90}), + }, + expectedShouldWatch: false, + }, + { + in: []string{"ks2/-70", "ks2/70-", "unknownKs/-", "ks/-80"}, + tablet: &topodatapb.Tablet{ + Keyspace: "ks", + KeyRange: key.NewKeyRange([]byte{0x90}, []byte{0xa0}), + }, + expectedShouldWatch: false, + }, + } + + for _, tt := range testCases { + t.Run(fmt.Sprintf("%v-Tablet-%v-%v", strings.Join(tt.in, ","), tt.tablet.GetKeyspace(), tt.tablet.GetShard()), func(t *testing.T) { + clustersToWatch = tt.in + err := initializeShardsToWatch() + require.NoError(t, err) + assert.Equal(t, tt.expectedShouldWatch, shouldWatchTablet(tt.tablet)) + }) + } +} + +// TestInitializeShardsToWatch tests that we initialize the shardsToWatch map correctly +// using the `--clusters_to_watch` flag. +func TestInitializeShardsToWatch(t *testing.T) { + oldClustersToWatch := clustersToWatch + defer func() { + clustersToWatch = oldClustersToWatch + shardsToWatch = nil + }() + + testCases := []struct { + in []string + expected map[string][]*topodatapb.KeyRange + expectedErr string + }{ + { + in: []string{}, + expected: map[string][]*topodatapb.KeyRange{}, + }, + { + in: []string{"unknownKs"}, + expected: map[string][]*topodatapb.KeyRange{ + "unknownKs": { + key.NewCompleteKeyRange(), + }, + }, + }, + { + in: []string{"test/-"}, + expected: map[string][]*topodatapb.KeyRange{ + "test": { + key.NewCompleteKeyRange(), + }, + }, + }, + { + in: []string{"test/324"}, + expectedErr: `invalid key range "324" while parsing clusters to watch`, + }, + { + in: []string{"test/0"}, + expected: map[string][]*topodatapb.KeyRange{ + "test": { + key.NewCompleteKeyRange(), + }, + }, + }, + { + in: []string{"test/-", "test2/-80", "test2/80-"}, + expected: map[string][]*topodatapb.KeyRange{ + "test": { + key.NewCompleteKeyRange(), + }, + "test2": { + key.NewKeyRange(nil, []byte{0x80}), + key.NewKeyRange([]byte{0x80}, nil), + }, + }, + }, + { + // known keyspace + in: []string{keyspace}, + expected: map[string][]*topodatapb.KeyRange{ + keyspace: { + key.NewCompleteKeyRange(), + }, + }, + }, + { + // keyspace with trailing-slash + in: []string{keyspace + "/"}, + expected: map[string][]*topodatapb.KeyRange{ + keyspace: { + key.NewCompleteKeyRange(), + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(strings.Join(testCase.in, ","), func(t *testing.T) { + defer func() { + shardsToWatch = make(map[string][]*topodatapb.KeyRange, 0) + }() + clustersToWatch = testCase.in + err := initializeShardsToWatch() + if testCase.expectedErr != "" { + require.EqualError(t, err, testCase.expectedErr) + return + } + require.NoError(t, err) + require.Equal(t, testCase.expected, shardsToWatch) + }) + } +} + func TestRefreshTabletsInKeyspaceShard(t *testing.T) { // Store the old flags and restore on test completion oldTs := ts @@ -369,25 +585,6 @@ func TestGetLockAction(t *testing.T) { } } -// TestProcessHealth tests that the health of the process reflects that we have run the first discovery once correctly. -func TestProcessHealth(t *testing.T) { - require.False(t, process.FirstDiscoveryCycleComplete.Load()) - originalTs := ts - defer func() { - ts = originalTs - process.FirstDiscoveryCycleComplete.Store(false) - }() - // Verify in the beginning, we have the first DiscoveredOnce field false. - _, discoveredOnce := process.HealthTest() - require.False(t, discoveredOnce) - ts = memorytopo.NewServer(context.Background(), cell1) - populateAllInformation() - require.True(t, process.FirstDiscoveryCycleComplete.Load()) - // Verify after we populate all information, we have the first DiscoveredOnce field true. - _, discoveredOnce = process.HealthTest() - require.True(t, discoveredOnce) -} - func TestSetReadOnly(t *testing.T) { tests := []struct { name string diff --git a/go/vt/vtorc/logic/topology_recovery.go b/go/vt/vtorc/logic/topology_recovery.go index f14eca624c9..41c0ca5d398 100644 --- a/go/vt/vtorc/logic/topology_recovery.go +++ b/go/vt/vtorc/logic/topology_recovery.go @@ -29,6 +29,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/config" "vitess.io/vitess/go/vt/vtorc/inst" "vitess.io/vitess/go/vt/vtorc/util" @@ -170,13 +171,15 @@ func resolveRecovery(topologyRecovery *TopologyRecovery, successorInstance *inst } // recoverPrimaryHasPrimary resets the replication on the primary instance -func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { - _ = AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixPrimaryHasPrimary.", analysisEntry.AnalyzedInstanceAlias)) + message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixPrimaryHasPrimary.", analysisEntry.AnalyzedInstanceAlias) + logger.Warning(message) + _ = AuditTopologyRecovery(topologyRecovery, message) return false, nil, err } - log.Infof("Analysis: %v, will fix incorrect primaryship on %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("Analysis: %v, will fix incorrect primaryship on %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { @@ -186,6 +189,7 @@ func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.Replicati // Read the tablet information from the database to find the shard and keyspace of the tablet analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) if err != nil { + logger.Errorf("Failed to read instance %s, aborting recovery", analysisEntry.AnalyzedInstanceAlias) return false, nil, err } @@ -196,19 +200,22 @@ func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.Replicati // runEmergencyReparentOp runs a recovery for which we have to run ERS. Here waitForAllTablets is a boolean telling ERS whether it should wait for all the tablets // or is it okay to skip 1. -func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, recoveryName string, waitForAllTablets bool) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, recoveryName string, waitForAllTablets bool, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { // Read the tablet information from the database to find the shard and keyspace of the tablet tablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) if err != nil { + logger.Errorf("Failed to read instance %s, aborting recovery", analysisEntry.AnalyzedInstanceAlias) return false, nil, err } topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { - _ = AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another %v.", analysisEntry.AnalyzedInstanceAlias, recoveryName)) + message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another %v.", analysisEntry.AnalyzedInstanceAlias, recoveryName) + logger.Warning(message) + _ = AuditTopologyRecovery(topologyRecovery, message) return false, nil, err } - log.Infof("Analysis: %v, %v %+v", analysisEntry.Analysis, recoveryName, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("Analysis: %v, %v %+v", analysisEntry.Analysis, recoveryName, analysisEntry.AnalyzedInstanceAlias) var promotedReplica *inst.Instance // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. @@ -222,11 +229,11 @@ func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.Replication // we only log the warnings and errors explicitly, everything gets logged as an information message anyways in auditing topology recovery switch level { case logutilpb.Level_WARNING: - log.Warningf("ERS - %s", value) + logger.Warningf("ERS - %s", value) case logutilpb.Level_ERROR: - log.Errorf("ERS - %s", value) + logger.Errorf("ERS - %s", value) default: - log.Infof("ERS - %s", value) + logger.Infof("ERS - %s", value) } _ = AuditTopologyRecovery(topologyRecovery, value) })).ReparentShard(ctx, @@ -240,7 +247,7 @@ func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.Replication }, ) if err != nil { - log.Errorf("Error running ERS - %v", err) + logger.Errorf("Error running ERS - %v", err) } if ev != nil && ev.NewPrimary != nil { @@ -252,13 +259,13 @@ func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.Replication // recoverDeadPrimary checks a given analysis, decides whether to take action, and possibly takes action // Returns true when action was taken. -func recoverDeadPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { - return runEmergencyReparentOp(ctx, analysisEntry, "RecoverDeadPrimary", false) +func recoverDeadPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { + return runEmergencyReparentOp(ctx, analysisEntry, "RecoverDeadPrimary", false, logger) } // recoverPrimaryTabletDeleted tries to run a recovery for the case where the primary tablet has been deleted. -func recoverPrimaryTabletDeleted(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { - return runEmergencyReparentOp(ctx, analysisEntry, "PrimaryTabletDeleted", true) +func recoverPrimaryTabletDeleted(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { + return runEmergencyReparentOp(ctx, analysisEntry, "PrimaryTabletDeleted", true, logger) } func postErsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.ReplicationAnalysis, recoveryName string, promotedReplica *inst.Instance) { @@ -271,12 +278,14 @@ func postErsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.R } // checkAndRecoverGenericProblem is a general-purpose recovery function -func checkAndRecoverLockedSemiSyncPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func checkAndRecoverLockedSemiSyncPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { + logger.Warning("No actions in checkAndRecoverLockedSemiSyncPrimary") return false, nil, nil } // checkAndRecoverGenericProblem is a general-purpose recovery function -func checkAndRecoverGenericProblem(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (bool, *TopologyRecovery, error) { +func checkAndRecoverGenericProblem(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (bool, *TopologyRecovery, error) { + logger.Warning("No actions in checkAndRecoverGenericProblem") return false, nil, nil } @@ -284,7 +293,7 @@ func checkAndRecoverGenericProblem(ctx context.Context, analysisEntry *inst.Repl func getCheckAndRecoverFunctionCode(analysisCode inst.AnalysisCode, tabletAlias string) recoveryFunction { switch analysisCode { // primary - case inst.DeadPrimary, inst.DeadPrimaryAndSomeReplicas: + case inst.DeadPrimary, inst.DeadPrimaryAndSomeReplicas, inst.PrimaryDiskStalled: // If ERS is disabled, we have no way of repairing the cluster. if !config.ERSEnabled() { log.Infof("VTOrc not configured to run ERS, skipping recovering %v", analysisCode) @@ -366,7 +375,7 @@ func hasActionableRecovery(recoveryFunctionCode recoveryFunction) bool { // getCheckAndRecoverFunction gets the recovery function for the given code. func getCheckAndRecoverFunction(recoveryFunctionCode recoveryFunction) ( - checkAndRecoverFunction func(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error), + checkAndRecoverFunction func(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error), ) { switch recoveryFunctionCode { case noRecoveryFunc: @@ -446,16 +455,20 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er countPendingRecoveries.Add(1) defer countPendingRecoveries.Add(-1) + logger := log.NewPrefixedLogger(fmt.Sprintf("Recovery for %s on %s/%s", analysisEntry.Analysis, analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard)) + logger.Info("Starting checkAndRecover") + checkAndRecoverFunctionCode := getCheckAndRecoverFunctionCode(analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) isActionableRecovery := hasActionableRecovery(checkAndRecoverFunctionCode) analysisEntry.IsActionableRecovery = isActionableRecovery if checkAndRecoverFunctionCode == noRecoveryFunc { + logger.Warning("No recovery strategies for problem, aborting recovery") // Unhandled problem type if analysisEntry.Analysis != inst.NoProblem { if util.ClearToLog("executeCheckAndRecoverFunction", analysisEntry.AnalyzedInstanceAlias) { - log.Warningf("executeCheckAndRecoverFunction: ignoring analysisEntry that has no action plan: %+v; tablet: %+v", - analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Warningf("executeCheckAndRecoverFunction: ignoring analysisEntry that has no action plan: tablet: %+v", + analysisEntry.AnalyzedInstanceAlias) } } @@ -463,24 +476,24 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er } // we have a recovery function; its execution still depends on filters if not disabled. if isActionableRecovery || util.ClearToLog("executeCheckAndRecoverFunction: detection", analysisEntry.AnalyzedInstanceAlias) { - log.Infof("executeCheckAndRecoverFunction: proceeding with %+v detection on %+v; isActionable?: %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias, isActionableRecovery) + logger.Infof("executeCheckAndRecoverFunction: proceeding with %+v detection on %+v; isActionable?: %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias, isActionableRecovery) } // At this point we have validated there's a failure scenario for which we have a recovery path. // Record the failure detected in the logs. err = InsertRecoveryDetection(analysisEntry) if err != nil { - log.Errorf("executeCheckAndRecoverFunction: error on inserting recovery detection record: %+v", err) + logger.Errorf("executeCheckAndRecoverFunction: error inserting recovery detection record, aborting recovery: %+v", err) return err } // Check for recovery being disabled globally if recoveryDisabledGlobally, err := IsRecoveryDisabled(); err != nil { // Unexpected. Shouldn't get this - log.Errorf("Unable to determine if recovery is disabled globally: %v", err) + logger.Errorf("Unable to determine if recovery is disabled globally, still attempting to recover: %v", err) } else if recoveryDisabledGlobally { - log.Infof("CheckAndRecover: Analysis: %+v, Tablet: %+v: NOT Recovering host (disabled globally)", - analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("CheckAndRecover: Tablet: %+v: NOT Recovering host (disabled globally)", + analysisEntry.AnalyzedInstanceAlias) return err } @@ -488,6 +501,7 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er // We lock the shard here and then refresh the tablets information ctx, unlock, err := LockShard(context.Background(), analysisEntry.AnalyzedInstanceAlias, getLockAction(analysisEntry.AnalyzedInstanceAlias, analysisEntry.Analysis)) if err != nil { + logger.Errorf("Failed to lock shard, aborting recovery: %v", err) return err } defer unlock(&err) @@ -497,7 +511,7 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er // changes, we should be checking that this failure is indeed needed to be fixed. We do this after locking the shard to be sure // that the data that we use now is up-to-date. if isActionableRecovery { - log.Errorf("executeCheckAndRecoverFunction: Proceeding with %v recovery on %v validation after acquiring shard lock.", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("executeCheckAndRecoverFunction: Proceeding with %v recovery on %v validation after acquiring shard lock.", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) // The first step we have to do is refresh the keyspace and shard information // This is required to know if the durability policies have changed or not // If they have, then recoveries like ReplicaSemiSyncMustNotBeSet, etc won't be valid anymore. @@ -505,6 +519,7 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er // a change in the recovery we run. err = RefreshKeyspaceAndShard(analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard) if err != nil { + logger.Errorf("Failed to refresh keyspace and shard, aborting recovery: %v", err) return err } // If we are about to run a cluster-wide recovery, it is imperative to first refresh all the tablets @@ -517,6 +532,7 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er } // We ignore the dead primary tablet because it is going to be unreachable. If all the other tablets aren't able to reach this tablet either, // we can proceed with the dead primary recovery. We don't need to refresh the information for this dead tablet. + logger.Info("Force refreshing all shard tablets") forceRefreshAllTabletsInShard(ctx, analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard, tabletsToIgnore) } else { // If we are not running a cluster-wide recovery, then it is only concerned with the specific tablet @@ -525,66 +541,76 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er // and the host-port set on the tablet in question. // So, we only need to refresh the tablet info records (to know if the primary tablet has changed), // and the replication data of the new primary and this tablet. + logger.Info("Refreshing shard tablet info") refreshTabletInfoOfShard(ctx, analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard) + logger.Info("Discovering analysis instance") DiscoverInstance(analysisEntry.AnalyzedInstanceAlias, true) + logger.Info("Getting shard primary") primaryTablet, err := shardPrimary(analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard) if err != nil { - log.Errorf("executeCheckAndRecoverFunction: Analysis: %+v, Tablet: %+v: error while finding the shard primary: %v", - analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias, err) + logger.Errorf("executeCheckAndRecoverFunction: Tablet: %+v: error while finding the shard primary: %v", + analysisEntry.AnalyzedInstanceAlias, err) return err } primaryTabletAlias := topoproto.TabletAliasString(primaryTablet.Alias) // We can skip the refresh if we know the tablet we are looking at is the primary tablet. // This would be the case for PrimaryHasPrimary recovery. We don't need to refresh the same tablet twice. if analysisEntry.AnalyzedInstanceAlias != primaryTabletAlias { + logger.Info("Discovering primary instance") DiscoverInstance(primaryTabletAlias, true) } } alreadyFixed, err := checkIfAlreadyFixed(analysisEntry) if err != nil { - log.Errorf("executeCheckAndRecoverFunction: Analysis: %+v, Tablet: %+v: error while trying to find if the problem is already fixed: %v", - analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias, err) + logger.Errorf("executeCheckAndRecoverFunction: Tablet: %+v: error while trying to find if the problem is already fixed: %v", + analysisEntry.AnalyzedInstanceAlias, err) return err } if alreadyFixed { - log.Infof("Analysis: %v on tablet %v - No longer valid, some other agent must have fixed the problem.", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("Analysis: %v on tablet %v - No longer valid, some other agent must have fixed the problem.", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) return nil } } // Actually attempt recovery: if isActionableRecovery || util.ClearToLog("executeCheckAndRecoverFunction: recovery", analysisEntry.AnalyzedInstanceAlias) { - log.Infof("executeCheckAndRecoverFunction: proceeding with %+v recovery on %+v; isRecoverable?: %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias, isActionableRecovery) + logger.Infof("executeCheckAndRecoverFunction: proceeding with recovery on %+v; isRecoverable?: %+v", analysisEntry.AnalyzedInstanceAlias, isActionableRecovery) } - recoveryAttempted, topologyRecovery, err := getCheckAndRecoverFunction(checkAndRecoverFunctionCode)(ctx, analysisEntry) + recoveryAttempted, topologyRecovery, err := getCheckAndRecoverFunction(checkAndRecoverFunctionCode)(ctx, analysisEntry, logger) if !recoveryAttempted { + logger.Errorf("Recovery not attempted: %+v", err) return err } recoveryName := getRecoverFunctionName(checkAndRecoverFunctionCode) recoveriesCounter.Add(recoveryName, 1) if err != nil { + logger.Errorf("Failed to recover: %+v", err) recoveriesFailureCounter.Add(recoveryName, 1) } else { + logger.Info("Recovery succeeded") recoveriesSuccessfulCounter.Add(recoveryName, 1) } if topologyRecovery == nil { + logger.Error("Topology recovery is nil - recovery might have failed") return err } if b, err := json.Marshal(topologyRecovery); err == nil { - log.Infof("Topology recovery: %+v", string(b)) + logger.Infof("Topology recovery: %+v", string(b)) } else { - log.Infof("Topology recovery: %+v", topologyRecovery) + logger.Infof("Topology recovery: %+v", topologyRecovery) } // If we ran a cluster wide recovery and actually attempted it, then we know that the replication state for all the tablets in this cluster // would have changed. So we can go ahead and pre-emptively refresh them. // For this refresh we don't use the same context that we used for the recovery, since that context might have expired or could expire soon // Instead we pass the background context. The call forceRefreshAllTabletsInShard handles adding a timeout to it for us. if isClusterWideRecovery(checkAndRecoverFunctionCode) { + logger.Info("Forcing refresh of all tablets post recovery") forceRefreshAllTabletsInShard(context.Background(), analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard, nil) } else { // For all other recoveries, we would have changed the replication status of the analyzed tablet // so it doesn't hurt to re-read the information of this tablet, otherwise we'll requeue the same recovery // that we just completed because we would be using stale data. + logger.Info("Force discovering problem instance %s post recovery", analysisEntry.AnalyzedInstanceAlias) DiscoverInstance(analysisEntry.AnalyzedInstanceAlias, true) } return err @@ -666,13 +692,15 @@ func postPrsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.R } // electNewPrimary elects a new primary while none were present before. -func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil || err != nil { - _ = AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another electNewPrimary.", analysisEntry.AnalyzedInstanceAlias)) + message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another electNewPrimary.", analysisEntry.AnalyzedInstanceAlias) + logger.Warning(message) + _ = AuditTopologyRecovery(topologyRecovery, message) return false, nil, err } - log.Infof("Analysis: %v, will elect a new primary for %v:%v", analysisEntry.Analysis, analysisEntry.ClusterDetails.Keyspace, analysisEntry.ClusterDetails.Shard) + logger.Infof("Analysis: %v, will elect a new primary for %v:%v", analysisEntry.Analysis, analysisEntry.ClusterDetails.Keyspace, analysisEntry.ClusterDetails.Shard) var promotedReplica *inst.Instance // This has to be done in the end; whether successful or not, we should mark that the recovery is done. @@ -683,6 +711,7 @@ func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysi analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) if err != nil { + logger.Errorf("Failed to read instance %s, aborting recovery", analysisEntry.AnalyzedInstanceAlias) return false, topologyRecovery, err } _ = AuditTopologyRecovery(topologyRecovery, "starting PlannedReparentShard for electing new primary.") @@ -693,9 +722,9 @@ func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysi // we only log the warnings and errors explicitly, everything gets logged as an information message anyways in auditing topology recovery switch level { case logutilpb.Level_WARNING: - log.Warningf("PRS - %s", value) + logger.Warningf("PRS - %s", value) case logutilpb.Level_ERROR: - log.Errorf("PRS - %s", value) + logger.Errorf("PRS - %s", value) } _ = AuditTopologyRecovery(topologyRecovery, value) })).ReparentShard(ctx, @@ -715,13 +744,15 @@ func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysi } // fixPrimary sets the primary as read-write. -func fixPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func fixPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { - _ = AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixPrimary.", analysisEntry.AnalyzedInstanceAlias)) + message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixPrimary.", analysisEntry.AnalyzedInstanceAlias) + logger.Warning(message) + _ = AuditTopologyRecovery(topologyRecovery, message) return false, nil, err } - log.Infof("Analysis: %v, will fix primary to read-write %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("Analysis: %v, will fix primary to read-write %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { @@ -730,29 +761,32 @@ func fixPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (r analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) if err != nil { + logger.Errorf("Failed to read instance %s, aborting recovery", analysisEntry.AnalyzedInstanceAlias) return false, topologyRecovery, err } durabilityPolicy, err := inst.GetDurabilityPolicy(analyzedTablet.Keyspace) if err != nil { - log.Info("Could not read the durability policy for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) + logger.Info("Could not read the durability policy for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) return false, topologyRecovery, err } - if err := tabletUndoDemotePrimary(ctx, analyzedTablet, reparentutil.SemiSyncAckers(durabilityPolicy, analyzedTablet) > 0); err != nil { + if err := tabletUndoDemotePrimary(ctx, analyzedTablet, policy.SemiSyncAckers(durabilityPolicy, analyzedTablet) > 0); err != nil { return true, topologyRecovery, err } return true, topologyRecovery, nil } // fixReplica sets the replica as read-only and points it at the current primary. -func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { - _ = AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixReplica.", analysisEntry.AnalyzedInstanceAlias)) + message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixReplica.", analysisEntry.AnalyzedInstanceAlias) + logger.Warning(message) + _ = AuditTopologyRecovery(topologyRecovery, message) return false, nil, err } - log.Infof("Analysis: %v, will fix replica %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("Analysis: %v, will fix replica %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { @@ -761,39 +795,42 @@ func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (r analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) if err != nil { + logger.Errorf("Failed to read instance %s, aborting recovery", analysisEntry.AnalyzedInstanceAlias) return false, topologyRecovery, err } primaryTablet, err := shardPrimary(analyzedTablet.Keyspace, analyzedTablet.Shard) if err != nil { - log.Info("Could not compute primary for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) + logger.Info("Could not compute primary for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) return false, topologyRecovery, err } durabilityPolicy, err := inst.GetDurabilityPolicy(analyzedTablet.Keyspace) if err != nil { - log.Info("Could not read the durability policy for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) + logger.Info("Could not read the durability policy for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) return false, topologyRecovery, err } err = setReadOnly(ctx, analyzedTablet) if err != nil { - log.Info("Could not set the tablet %v to readonly - %v", analysisEntry.AnalyzedInstanceAlias, err) + logger.Info("Could not set the tablet %v to readonly - %v", analysisEntry.AnalyzedInstanceAlias, err) return true, topologyRecovery, err } - err = setReplicationSource(ctx, analyzedTablet, primaryTablet, reparentutil.IsReplicaSemiSync(durabilityPolicy, primaryTablet, analyzedTablet), float64(analysisEntry.ReplicaNetTimeout)/2) + err = setReplicationSource(ctx, analyzedTablet, primaryTablet, policy.IsReplicaSemiSync(durabilityPolicy, primaryTablet, analyzedTablet), float64(analysisEntry.ReplicaNetTimeout)/2) return true, topologyRecovery, err } // recoverErrantGTIDDetected changes the tablet type of a replica tablet that has errant GTIDs. -func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.ReplicationAnalysis) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { - _ = AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another recoverErrantGTIDDetected.", analysisEntry.AnalyzedInstanceAlias)) + message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another recoverErrantGTIDDetected.", analysisEntry.AnalyzedInstanceAlias) + logger.Warning(message) + _ = AuditTopologyRecovery(topologyRecovery, message) return false, nil, err } - log.Infof("Analysis: %v, will fix tablet %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + logger.Infof("Analysis: %v, will fix tablet %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { @@ -807,16 +844,16 @@ func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.Replicat primaryTablet, err := shardPrimary(analyzedTablet.Keyspace, analyzedTablet.Shard) if err != nil { - log.Info("Could not compute primary for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) + logger.Info("Could not compute primary for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) return false, topologyRecovery, err } durabilityPolicy, err := inst.GetDurabilityPolicy(analyzedTablet.Keyspace) if err != nil { - log.Info("Could not read the durability policy for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) + logger.Info("Could not read the durability policy for %v/%v", analyzedTablet.Keyspace, analyzedTablet.Shard) return false, topologyRecovery, err } - err = changeTabletType(ctx, analyzedTablet, topodatapb.TabletType_DRAINED, reparentutil.IsReplicaSemiSync(durabilityPolicy, primaryTablet, analyzedTablet)) + err = changeTabletType(ctx, analyzedTablet, topodatapb.TabletType_DRAINED, policy.IsReplicaSemiSync(durabilityPolicy, primaryTablet, analyzedTablet)) return true, topologyRecovery, err } diff --git a/go/vt/vtorc/logic/topology_recovery_test.go b/go/vt/vtorc/logic/topology_recovery_test.go index f7658060b95..9df5fc989f0 100644 --- a/go/vt/vtorc/logic/topology_recovery_test.go +++ b/go/vt/vtorc/logic/topology_recovery_test.go @@ -20,6 +20,8 @@ import ( "context" "testing" + "vitess.io/vitess/go/vt/log" + "github.com/stretchr/testify/require" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -42,6 +44,11 @@ func TestAnalysisEntriesHaveSameRecovery(t *testing.T) { prevAnalysisCode: inst.DeadPrimary, newAnalysisCode: inst.DeadPrimaryAndSomeReplicas, shouldBeEqual: true, + }, { + // DeadPrimary and StalledDiskPrimary have the same recovery + prevAnalysisCode: inst.DeadPrimary, + newAnalysisCode: inst.PrimaryDiskStalled, + shouldBeEqual: true, }, { // DeadPrimary and PrimaryTabletDeleted are different recoveries. prevAnalysisCode: inst.DeadPrimary, @@ -126,7 +133,7 @@ func TestElectNewPrimaryPanic(t *testing.T) { defer cancel() ts = memorytopo.NewServer(ctx, "zone1") - recoveryAttempted, _, err := electNewPrimary(context.Background(), analysisEntry) + recoveryAttempted, _, err := electNewPrimary(context.Background(), analysisEntry, log.NewPrefixedLogger("prefix")) require.True(t, recoveryAttempted) require.Error(t, err) } @@ -215,6 +222,16 @@ func TestGetCheckAndRecoverFunctionCode(t *testing.T) { ersEnabled: false, analysisCode: inst.DeadPrimary, wantRecoveryFunction: noRecoveryFunc, + }, { + name: "StalledDiskPrimary with ERS enabled", + ersEnabled: true, + analysisCode: inst.PrimaryDiskStalled, + wantRecoveryFunction: recoverDeadPrimaryFunc, + }, { + name: "StalledDiskPrimary with ERS disabled", + ersEnabled: false, + analysisCode: inst.PrimaryDiskStalled, + wantRecoveryFunction: noRecoveryFunc, }, { name: "PrimaryTabletDeleted with ERS enabled", ersEnabled: true, diff --git a/go/vt/vtorc/logic/vtorc.go b/go/vt/vtorc/logic/vtorc.go index b8cf404d050..5ac5af50d47 100644 --- a/go/vt/vtorc/logic/vtorc.go +++ b/go/vt/vtorc/logic/vtorc.go @@ -17,12 +17,14 @@ package logic import ( + "context" "sync" "sync/atomic" "time" "github.com/patrickmn/go-cache" "github.com/sjmudd/stopwatch" + "golang.org/x/sync/errgroup" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/log" @@ -32,6 +34,7 @@ import ( "vitess.io/vitess/go/vt/vtorc/discovery" "vitess.io/vitess/go/vt/vtorc/inst" ometrics "vitess.io/vitess/go/vt/vtorc/metrics" + "vitess.io/vitess/go/vt/vtorc/process" "vitess.io/vitess/go/vt/vtorc/util" ) @@ -105,7 +108,7 @@ func waitForLocksRelease() { // handleDiscoveryRequests iterates the discoveryQueue channel and calls upon // instance discovery per entry. func handleDiscoveryRequests() { - discoveryQueue = discovery.CreateOrReturnQueue("DEFAULT") + discoveryQueue = discovery.CreateQueue("DEFAULT") // create a pool of discovery workers for i := uint(0); i < config.DiscoveryMaxConcurrency; i++ { go func() { @@ -304,30 +307,34 @@ func ContinuousDiscovery() { go inst.SnapshotTopologies() }() case <-tabletTopoTick: - refreshAllInformation() + ctx, cancel := context.WithTimeout(context.Background(), config.GetTopoInformationRefreshDuration()) + if err := refreshAllInformation(ctx); err != nil { + log.Errorf("failed to refresh topo information: %+v", err) + } + cancel() } } } // refreshAllInformation refreshes both shard and tablet information. This is meant to be run on tablet topo ticks. -func refreshAllInformation() { - // Create a wait group - var wg sync.WaitGroup +func refreshAllInformation(ctx context.Context) error { + // Create an errgroup + eg, ctx := errgroup.WithContext(ctx) // Refresh all keyspace information. - wg.Add(1) - go func() { - defer wg.Done() - RefreshAllKeyspacesAndShards() - }() + eg.Go(func() error { + return RefreshAllKeyspacesAndShards(ctx) + }) // Refresh all tablets. - wg.Add(1) - go func() { - defer wg.Done() - refreshAllTablets() - }() + eg.Go(func() error { + return refreshAllTablets(ctx) + }) // Wait for both the refreshes to complete - wg.Wait() + err := eg.Wait() + if err == nil { + process.FirstDiscoveryCycleComplete.Store(true) + } + return err } diff --git a/go/vt/vtorc/logic/vtorc_test.go b/go/vt/vtorc/logic/vtorc_test.go index c8f2ac3bfdc..edd8141e8b7 100644 --- a/go/vt/vtorc/logic/vtorc_test.go +++ b/go/vt/vtorc/logic/vtorc_test.go @@ -1,11 +1,17 @@ package logic import ( + "context" "sync/atomic" "testing" "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vtorc/db" + "vitess.io/vitess/go/vt/vtorc/process" ) func TestWaitForLocksRelease(t *testing.T) { @@ -54,3 +60,41 @@ func waitForLocksReleaseAndGetTimeWaitedFor() time.Duration { waitForLocksRelease() return time.Since(start) } + +func TestRefreshAllInformation(t *testing.T) { + // Store the old flags and restore on test completion + oldTs := ts + defer func() { + ts = oldTs + }() + + // Clear the database after the test. The easiest way to do that is to run all the initialization commands again. + defer func() { + db.ClearVTOrcDatabase() + }() + + // Verify in the beginning, we have the first DiscoveredOnce field false. + _, discoveredOnce := process.HealthTest() + require.False(t, discoveredOnce) + + // Create a memory topo-server and create the keyspace and shard records + ts = memorytopo.NewServer(context.Background(), cell1) + _, err := ts.GetOrCreateShard(context.Background(), keyspace, shard) + require.NoError(t, err) + + // Test error + ctx, cancel := context.WithCancel(context.Background()) + cancel() // cancel context to simulate timeout + require.Error(t, refreshAllInformation(ctx)) + require.False(t, process.FirstDiscoveryCycleComplete.Load()) + _, discoveredOnce = process.HealthTest() + require.False(t, discoveredOnce) + + // Test success + ctx2, cancel2 := context.WithCancel(context.Background()) + defer cancel2() + require.NoError(t, refreshAllInformation(ctx2)) + require.True(t, process.FirstDiscoveryCycleComplete.Load()) + _, discoveredOnce = process.HealthTest() + require.True(t, discoveredOnce) +} diff --git a/go/vt/vtorc/process/health.go b/go/vt/vtorc/process/health.go index f72d7b05210..d448f03bb83 100644 --- a/go/vt/vtorc/process/health.go +++ b/go/vt/vtorc/process/health.go @@ -62,7 +62,7 @@ func writeHealthToDatabase() bool { func HealthTest() (health *NodeHealth, discoveredOnce bool) { ThisNodeHealth.LastReported = time.Now() discoveredOnce = FirstDiscoveryCycleComplete.Load() - ThisNodeHealth.Healthy = writeHealthToDatabase() + ThisNodeHealth.Healthy = discoveredOnce && writeHealthToDatabase() return ThisNodeHealth, discoveredOnce } diff --git a/go/vt/vtorc/process/health_test.go b/go/vt/vtorc/process/health_test.go new file mode 100644 index 00000000000..c198deda4e4 --- /dev/null +++ b/go/vt/vtorc/process/health_test.go @@ -0,0 +1,46 @@ +/* +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 process + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestHealthTest(t *testing.T) { + defer func() { + FirstDiscoveryCycleComplete.Store(false) + ThisNodeHealth = &NodeHealth{} + }() + + require.Zero(t, ThisNodeHealth.LastReported) + require.False(t, ThisNodeHealth.Healthy) + + ThisNodeHealth = &NodeHealth{} + health, discoveredOnce := HealthTest() + require.False(t, health.Healthy) + require.False(t, discoveredOnce) + require.NotZero(t, ThisNodeHealth.LastReported) + + ThisNodeHealth = &NodeHealth{} + FirstDiscoveryCycleComplete.Store(true) + health, discoveredOnce = HealthTest() + require.True(t, health.Healthy) + require.True(t, discoveredOnce) + require.NotZero(t, ThisNodeHealth.LastReported) +} diff --git a/go/vt/vtorc/test/recovery_analysis.go b/go/vt/vtorc/test/recovery_analysis.go index 2a95d3b2b0e..bb6e4132243 100644 --- a/go/vt/vtorc/test/recovery_analysis.go +++ b/go/vt/vtorc/test/recovery_analysis.go @@ -62,7 +62,6 @@ type InfoForRecoveryAnalysis struct { DowntimeEndTimestamp string DowntimeRemainingSeconds int CountValidOracleGTIDReplicas uint - CountValidMariaDBGTIDReplicas uint CountValidBinlogServerReplicas uint SemiSyncPrimaryEnabled int SemiSyncPrimaryStatus int @@ -81,6 +80,7 @@ type InfoForRecoveryAnalysis struct { MaxReplicaGTIDMode string MaxReplicaGTIDErrant string ReadOnly uint + IsStalledDisk uint } func (info *InfoForRecoveryAnalysis) ConvertToRowMap() sqlutils.RowMap { @@ -94,7 +94,6 @@ func (info *InfoForRecoveryAnalysis) ConvertToRowMap() sqlutils.RowMap { rowMap["count_downtimed_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountDowntimedReplicas), Valid: true} rowMap["count_lagging_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountLaggingReplicas), Valid: true} rowMap["count_logging_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountLoggingReplicas), Valid: true} - rowMap["count_mariadb_gtid_replicas"] = sqlutils.CellData{Valid: false} rowMap["count_mixed_based_logging_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountMixedBasedLoggingReplicas), Valid: true} rowMap["count_oracle_gtid_replicas"] = sqlutils.CellData{Valid: false} rowMap["count_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountReplicas), Valid: true} @@ -102,7 +101,6 @@ func (info *InfoForRecoveryAnalysis) ConvertToRowMap() sqlutils.RowMap { rowMap["count_semi_sync_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountSemiSyncReplicasEnabled), Valid: true} rowMap["count_statement_based_logging_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountStatementBasedLoggingReplicas), Valid: true} rowMap["count_valid_binlog_server_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidBinlogServerReplicas), Valid: true} - rowMap["count_valid_mariadb_gtid_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidMariaDBGTIDReplicas), Valid: true} rowMap["count_valid_oracle_gtid_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidOracleGTIDReplicas), Valid: true} rowMap["count_valid_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidReplicas), Valid: true} rowMap["count_valid_replicating_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidReplicatingReplicas), Valid: true} @@ -148,6 +146,7 @@ func (info *InfoForRecoveryAnalysis) ConvertToRowMap() sqlutils.RowMap { rowMap["semi_sync_replica_enabled"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.SemiSyncReplicaEnabled), Valid: true} res, _ := prototext.Marshal(info.TabletInfo) rowMap["tablet_info"] = sqlutils.CellData{String: string(res), Valid: true} + rowMap["is_disk_stalled"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.IsStalledDisk), Valid: true} return rowMap } diff --git a/go/vt/vttablet/endtoend/connecttcp/main_test.go b/go/vt/vttablet/endtoend/connecttcp/main_test.go index 9d52b1287a1..43be05893cc 100644 --- a/go/vt/vttablet/endtoend/connecttcp/main_test.go +++ b/go/vt/vttablet/endtoend/connecttcp/main_test.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "testing" + "time" "vitess.io/vitess/go/mysql" vttestpb "vitess.io/vitess/go/vt/proto/vttest" @@ -86,8 +87,7 @@ func TestMain(m *testing.M) { defer cancel() config := tabletenv.NewDefaultConfig() - config.TwoPCEnable = true - config.TwoPCAbandonAge = 1 + config.TwoPCAbandonAge = 1 * time.Second if err := framework.StartCustomServer(ctx, connParams, connAppDebugParams, cluster.DbName(), config); err != nil { fmt.Fprintf(os.Stderr, "%v", err) diff --git a/go/vt/vttablet/endtoend/framework/server.go b/go/vt/vttablet/endtoend/framework/server.go index 0124bb992ba..3374aadb450 100644 --- a/go/vt/vttablet/endtoend/framework/server.go +++ b/go/vt/vttablet/endtoend/framework/server.go @@ -108,8 +108,7 @@ func StartCustomServer(ctx context.Context, connParams, connAppDebugParams mysql func StartServer(ctx context.Context, connParams, connAppDebugParams mysql.ConnParams, dbName string) error { config := tabletenv.NewDefaultConfig() config.StrictTableACL = true - config.TwoPCEnable = true - config.TwoPCAbandonAge = 1 + config.TwoPCAbandonAge = 1 * time.Second config.HotRowProtection.Mode = tabletenv.Enable config.TrackSchemaVersions = true config.GracePeriods.Shutdown = 2 * time.Second diff --git a/go/vt/vttablet/endtoend/misc_test.go b/go/vt/vttablet/endtoend/misc_test.go index 68f6f4b1af6..8d5630a5dd8 100644 --- a/go/vt/vttablet/endtoend/misc_test.go +++ b/go/vt/vttablet/endtoend/misc_test.go @@ -49,10 +49,7 @@ import ( func TestSimpleRead(t *testing.T) { vstart := framework.DebugVars() _, err := framework.NewClient().Execute("select * from vitess_test where intval=1", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) vend := framework.DebugVars() compareIntDiff(t, vend, "Queries/TotalCount", vstart, 1) compareIntDiff(t, vend, "Queries/Histograms/Select/Count", vstart, 1) @@ -69,15 +66,9 @@ func TestBinary(t *testing.T) { "(4, null, null, '\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\\x00\x0f\xf0\xff')", nil, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) qr, err := client.Execute("select binval from vitess_test where intval=4", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) want := sqltypes.Result{ Fields: []*querypb.Field{ { @@ -106,18 +97,10 @@ func TestBinary(t *testing.T) { "insert into vitess_test values(5, null, null, :bindata)", map[string]*querypb.BindVariable{"bindata": sqltypes.StringBindVariable(binaryData)}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) qr, err = client.Execute("select binval from vitess_test where intval=5", nil) - if err != nil { - t.Error(err) - return - } - if !qr.Equal(&want) { - t.Errorf("Execute: \n%#v, want \n%#v", prettyPrint(*qr), prettyPrint(want)) - } + require.NoError(t, err) + assert.Truef(t, qr.Equal(&want), "Execute: \n%#v, want \n%#v", prettyPrint(*qr), prettyPrint(want)) } func TestNocacheListArgs(t *testing.T) { @@ -130,10 +113,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{2, 3, 4}), }, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 2, len(qr.Rows)) qr, err = client.Execute( @@ -142,10 +122,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{3, 4}), }, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 1, len(qr.Rows)) qr, err = client.Execute( @@ -154,10 +131,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{3}), }, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 1, len(qr.Rows)) // Error case @@ -167,11 +141,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{}), }, ) - want := "empty list supplied for list (CallerID: dev)" - if err == nil || err.Error() != want { - t.Errorf("Error: %v, want %s", err, want) - return - } + assert.EqualError(t, err, "empty list supplied for list (CallerID: dev)") } func TestIntegrityError(t *testing.T) { @@ -179,9 +149,7 @@ func TestIntegrityError(t *testing.T) { client := framework.NewClient() _, err := client.Execute("insert into vitess_test values(1, null, null, null)", nil) want := "Duplicate entry '1'" - if err == nil || !strings.HasPrefix(err.Error(), want) { - t.Errorf("Error: %v, want prefix %s", err, want) - } + assert.ErrorContains(t, err, want) compareIntDiff(t, framework.DebugVars(), "Errors/ALREADY_EXISTS", vstart, 1) } @@ -197,10 +165,7 @@ func TestTrailingComment(t *testing.T) { "select * from vitess_test where intval=:ival /* comment1 */ /* comment2 */", } { _, err := client.Execute(query, bindVars) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) v2 := framework.Server.QueryPlanCacheLen() if v2 != v1+1 { t.Errorf("QueryEnginePlanCacheLength(%s): %d, want %d", query, v2, v1+1) @@ -211,17 +176,11 @@ func TestTrailingComment(t *testing.T) { func TestSchemaReload(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &connParams) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer conn.Close() _, err = conn.ExecuteFetch("create table vitess_temp(intval int)", 10, false) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer conn.ExecuteFetch("drop table vitess_temp", 10, false) framework.Server.ReloadSchema(context.Background()) @@ -246,10 +205,7 @@ func TestSchemaReload(t *testing.T) { func TestSidecarTables(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &connParams) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer conn.Close() for _, table := range []string{ "redo_state", @@ -258,10 +214,7 @@ func TestSidecarTables(t *testing.T) { "dt_participant", } { _, err = conn.ExecuteFetch(fmt.Sprintf("describe _vt.%s", table), 10, false) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) } } @@ -336,10 +289,7 @@ func TestBindInSelect(t *testing.T) { "select :bv from dual", map[string]*querypb.BindVariable{"bv": sqltypes.StringBindVariable("abcd")}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) want := &sqltypes.Result{ Fields: []*querypb.Field{{ Name: "abcd", @@ -365,10 +315,7 @@ func TestBindInSelect(t *testing.T) { "select :bv from dual", map[string]*querypb.BindVariable{"bv": sqltypes.StringBindVariable("\x00\xff")}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) want = &sqltypes.Result{ Fields: []*querypb.Field{{ Name: "", @@ -392,16 +339,10 @@ func TestBindInSelect(t *testing.T) { func TestHealth(t *testing.T) { response, err := http.Get(fmt.Sprintf("%s/debug/health", framework.ServerAddress)) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer response.Body.Close() result, err := io.ReadAll(response.Body) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) if string(result) != "ok" { t.Errorf("Health check: %s, want ok", result) } @@ -567,27 +508,18 @@ func TestDBAStatements(t *testing.T) { client := framework.NewClient() qr, err := client.Execute("show variables like 'version'", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) wantCol := sqltypes.NewVarChar("version") if !reflect.DeepEqual(qr.Rows[0][0], wantCol) { t.Errorf("Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol) } qr, err = client.Execute("describe vitess_a", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 4, len(qr.Rows)) qr, err = client.Execute("explain vitess_a", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 4, len(qr.Rows)) } @@ -664,37 +596,36 @@ func TestClientFoundRows(t *testing.T) { func TestLastInsertId(t *testing.T) { client := framework.NewClient() _, err := client.Execute("insert ignore into vitess_autoinc_seq SET name = 'foo', sequence = 0", nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer client.Execute("delete from vitess_autoinc_seq where name = 'foo'", nil) - - if err := client.Begin(true); err != nil { - t.Fatal(err) - } + err = client.Begin(true) + require.NoError(t, err) defer client.Rollback() res, err := client.Execute("insert ignore into vitess_autoinc_seq SET name = 'foo', sequence = 0", nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) qr, err := client.Execute("update vitess_autoinc_seq set sequence=last_insert_id(sequence + 1) where name='foo'", nil) require.NoError(t, err) insID := res.InsertID - - if want, got := insID+1, qr.InsertID; want != got { - t.Errorf("insertId mismatch; got %v, want %v", got, want) - } + assert.Equal(t, insID+1, qr.InsertID, "insertID") qr, err = client.Execute("select sequence from vitess_autoinc_seq where name = 'foo'", nil) require.NoError(t, err) wantCol := sqltypes.NewUint64(insID + uint64(1)) - if !reflect.DeepEqual(qr.Rows[0][0], wantCol) { - t.Errorf("Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol) - } + assert.Truef(t, qr.Rows[0][0].Equal(wantCol), "Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol) +} + +func TestSelectLastInsertId(t *testing.T) { + client := framework.NewClient() + rs, err := client.ExecuteWithOptions("select 1 from dual where last_insert_id(42) = 42", nil, &querypb.ExecuteOptions{ + IncludedFields: querypb.ExecuteOptions_ALL, + FetchLastInsertId: true, + }) + require.NoError(t, err) + assert.EqualValues(t, 42, rs.InsertID) } func TestAppDebugRequest(t *testing.T) { @@ -781,10 +712,7 @@ func TestSelectBooleanSystemVariables(t *testing.T) { fmt.Sprintf("select :%s", tc.Variable), map[string]*querypb.BindVariable{tc.Variable: sqltypes.BoolBindVariable(tc.Value)}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) require.NotEmpty(t, qr.Fields, "fields should not be empty") require.Equal(t, tc.Type, qr.Fields[0].Type, fmt.Sprintf("invalid type, wants: %+v, but got: %+v\n", tc.Type, qr.Fields[0].Type)) } diff --git a/go/vt/vttablet/endtoend/twopc/main_test.go b/go/vt/vttablet/endtoend/twopc/main_test.go index 090751503d4..3b68ce273e1 100644 --- a/go/vt/vttablet/endtoend/twopc/main_test.go +++ b/go/vt/vttablet/endtoend/twopc/main_test.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "testing" + "time" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/vttablet/endtoend/framework" @@ -83,8 +84,7 @@ func TestMain(m *testing.M) { defer cancel() config := tabletenv.NewDefaultConfig() - config.TwoPCEnable = true - config.TwoPCAbandonAge = 1 + config.TwoPCAbandonAge = 1 * time.Second err := framework.StartCustomServer(ctx, connParams, connAppDebugParams, cluster.DbName(), config) if err != nil { fmt.Fprintf(os.Stderr, "%v", err) diff --git a/go/vt/vttablet/filelogger/filelogger_test.go b/go/vt/vttablet/filelogger/filelogger_test.go index f747ebba93b..47602e1a855 100644 --- a/go/vt/vttablet/filelogger/filelogger_test.go +++ b/go/vt/vttablet/filelogger/filelogger_test.go @@ -75,11 +75,6 @@ func TestFileLog(t *testing.T) { // TestFileLog sends a stream of five query records to the plugin, and verifies that they are logged. func TestFileLogRedacted(t *testing.T) { - streamlog.SetRedactDebugUIQueries(true) - defer func() { - streamlog.SetRedactDebugUIQueries(false) - }() - dir := t.TempDir() logPath := path.Join(dir, "test.log") @@ -94,7 +89,9 @@ func TestFileLogRedacted(t *testing.T) { log1 := &tabletenv.LogStats{ Ctx: ctx, OriginalSQL: "test 1", + Config: streamlog.NewQueryLogConfigForTest(), } + log1.Config.RedactDebugUIQueries = true log1.AddRewrittenSQL("test 1 PII", time.Time{}) log1.MysqlResponseTime = 0 tabletenv.StatsLogger.Send(log1) @@ -102,7 +99,9 @@ func TestFileLogRedacted(t *testing.T) { log2 := &tabletenv.LogStats{ Ctx: ctx, OriginalSQL: "test 2", + Config: streamlog.NewQueryLogConfigForTest(), } + log2.Config.RedactDebugUIQueries = true log2.AddRewrittenSQL("test 2 PII", time.Time{}) log2.MysqlResponseTime = 0 tabletenv.StatsLogger.Send(log2) diff --git a/go/vt/vttablet/grpctmclient/client.go b/go/vt/vttablet/grpctmclient/client.go index 20aa1e5f39f..01d51e2993a 100644 --- a/go/vt/vttablet/grpctmclient/client.go +++ b/go/vt/vttablet/grpctmclient/client.go @@ -63,7 +63,7 @@ var ( name string ) -func registerFlags(fs *pflag.FlagSet) { +func RegisterFlags(fs *pflag.FlagSet) { fs.IntVar(&concurrency, "tablet_manager_grpc_concurrency", concurrency, "concurrency to use to talk to a vttablet server for performance-sensitive RPCs (like ExecuteFetchAs{Dba,App}, CheckThrottler and FullStatus)") fs.StringVar(&cert, "tablet_manager_grpc_cert", cert, "the cert to use to connect") fs.StringVar(&key, "tablet_manager_grpc_key", key, "the key to use to connect") @@ -92,7 +92,7 @@ func init() { }) for _, cmd := range _binaries { - servenv.OnParseFor(cmd, registerFlags) + servenv.OnParseFor(cmd, RegisterFlags) } } diff --git a/go/vt/vttablet/grpctmserver/server.go b/go/vt/vttablet/grpctmserver/server.go index 889448a7cd3..6f0fd2aa4dc 100644 --- a/go/vt/vttablet/grpctmserver/server.go +++ b/go/vt/vttablet/grpctmserver/server.go @@ -354,7 +354,7 @@ func (s *server) MysqlHostMetrics(ctx context.Context, request *tabletmanagerdat func (s *server) ReplicationStatus(ctx context.Context, request *tabletmanagerdatapb.ReplicationStatusRequest) (response *tabletmanagerdatapb.ReplicationStatusResponse, err error) { defer s.tm.HandleRPCPanic(ctx, "ReplicationStatus", request, response, false /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) - response = &tabletmanagerdatapb.ReplicationStatusResponse{BackupRunning: s.tm.IsBackupRunning()} + response = &tabletmanagerdatapb.ReplicationStatusResponse{} status, err := s.tm.ReplicationStatus(ctx) if err == nil { response.Status = status @@ -638,8 +638,6 @@ func (s *server) StopReplicationAndGetStatus(ctx context.Context, request *table response.Status = statusResponse.Status } - response.BackupRunning = s.tm.IsBackupRunning() - return response, err } diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index f8b5cfd9b8d..76c7af7fc2e 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -838,34 +838,41 @@ func (e *Executor) killTableLockHoldersAndAccessors(ctx context.Context, tableNa } } capableOf := mysql.ServerVersionCapableOf(conn.ServerVersion) - capable, err := capableOf(capabilities.PerformanceSchemaDataLocksTableCapability) - if err != nil { - return err - } - if capable { - { - // Kill connections that have open transactions locking the table. These potentially (probably?) are not - // actively running a query on our table. They're doing other things while holding locks on our table. - query, err := sqlparser.ParseAndBind(sqlProcessWithLocksOnTable, sqltypes.StringBindVariable(tableName)) - if err != nil { - return err - } - rs, err := conn.Conn.ExecuteFetch(query, -1, true) + terminateTransactions := func(capability capabilities.FlavorCapability, query string, column string, description string) error { + capable, err := capableOf(capability) + if err != nil { + return err + } + if !capable { + return nil + } + query, err = sqlparser.ParseAndBind(query, sqltypes.StringBindVariable(tableName)) + if err != nil { + return err + } + rs, err := conn.Conn.ExecuteFetch(query, -1, true) + if err != nil { + return vterrors.Wrapf(err, "finding transactions locking table `%s` %s", tableName, description) + } + log.Infof("terminateTransactions: found %v transactions locking table `%s` %s", len(rs.Rows), tableName, description) + for _, row := range rs.Named().Rows { + threadId := row.AsInt64(column, 0) + log.Infof("terminateTransactions: killing connection %v with transaction locking table `%s` %s", threadId, tableName, description) + killConnection := fmt.Sprintf("KILL %d", threadId) + _, err = conn.Conn.ExecuteFetch(killConnection, 1, false) if err != nil { - return vterrors.Wrapf(err, "finding transactions locking table") - } - log.Infof("killTableLockHoldersAndAccessors: found %v locking transactions", len(rs.Rows)) - for _, row := range rs.Named().Rows { - threadId := row.AsInt64("trx_mysql_thread_id", 0) - log.Infof("killTableLockHoldersAndAccessors: killing connection %v with transaction on table", threadId) - killConnection := fmt.Sprintf("KILL %d", threadId) - _, err = conn.Conn.ExecuteFetch(killConnection, 1, false) - if err != nil { - log.Errorf("Unable to kill the connection %d: %v", threadId, err) - } + log.Errorf("terminateTransactions: unable to kill the connection %d locking table `%s` %s: %v", threadId, tableName, description, err) } } + return nil + } + if err := terminateTransactions(capabilities.PerformanceSchemaDataLocksTableCapability, sqlProcessWithLocksOnTable, "trx_mysql_thread_id", "data"); err != nil { + return err } + if err := terminateTransactions(capabilities.PerformanceSchemaMetadataLocksTableCapability, sqlProcessWithMetadataLocksOnTable, "processlist_id", "metadata"); err != nil { + return err + } + return nil } @@ -968,7 +975,9 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh defer preparationConnRestoreLockWaitTimeout() if needsShadowTableAnalysis { - // Run `ANALYZE TABLE` on the vreplication table so that it has up-to-date statistics at cut-over + // Run `ANALYZE TABLE` on the vreplication table so that it has up-to-date statistics at cut-over. + // The statement will be replicated, so that in case there's a PRS/ERS shortly after cut-over, the + // promoted replica will have good statistics. parsed := sqlparser.BuildParsedQuery(sqlAnalyzeTable, vreplTable) if _, err := preparationsConn.Conn.Exec(ctx, parsed.Query, -1, false); err != nil { // Best effort only. Do not fail the mgiration if this fails. diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index 943a3b1df07..6c0bff1086f 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -499,7 +499,8 @@ const ( sqlDropTable = "DROP TABLE `%a`" sqlDropTableIfExists = "DROP TABLE IF EXISTS `%a`" sqlShowTableStatus = "SHOW TABLE STATUS LIKE '%a'" - sqlAnalyzeTable = "ANALYZE NO_WRITE_TO_BINLOG TABLE `%a`" + sqlAnalyzeTableLocal = "ANALYZE NO_WRITE_TO_BINLOG TABLE `%a`" + sqlAnalyzeTable = "ANALYZE TABLE `%a`" sqlShowCreateTable = "SHOW CREATE TABLE `%a`" sqlShowVariablesLikePreserveForeignKey = "show global variables like 'rename_table_preserve_foreign_key'" sqlShowVariablesLikeFastAnalyzeTable = "show global variables like 'fast_analyze_table'" @@ -566,6 +567,15 @@ const ( where data_locks.OBJECT_SCHEMA=database() AND data_locks.OBJECT_NAME=%a ` + sqlProcessWithMetadataLocksOnTable = ` + SELECT + DISTINCT threads.processlist_id + from + performance_schema.metadata_locks + join performance_schema.threads on (metadata_locks.OWNER_THREAD_ID=threads.THREAD_ID) + where + metadata_locks.OBJECT_SCHEMA=database() AND metadata_locks.OBJECT_NAME=%a + ` ) var ( diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 2761c27c801..b00bcc40894 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -208,7 +208,7 @@ func (v *VRepl) executeAnalyzeTable(ctx context.Context, conn *dbconnpool.DBConn defer conn.ExecuteFetch(sqlDisableFastAnalyzeTable, 1, false) } - parsed := sqlparser.BuildParsedQuery(sqlAnalyzeTable, tableName) + parsed := sqlparser.BuildParsedQuery(sqlAnalyzeTableLocal, tableName) if _, err := conn.ExecuteFetch(parsed.Query, 1, false); err != nil { return err } diff --git a/go/vt/vttablet/sysloglogger/sysloglogger_test.go b/go/vt/vttablet/sysloglogger/sysloglogger_test.go index 3a06b98ed1c..835f6b71b48 100644 --- a/go/vt/vttablet/sysloglogger/sysloglogger_test.go +++ b/go/vt/vttablet/sysloglogger/sysloglogger_test.go @@ -50,13 +50,14 @@ func (fw *fakeWriter) Info(msg string) error { return fw.write(syslog.LOG_INFO, func (fw *fakeWriter) Close() error { return nil } // mockLogStats generates a dummy tabletserver.LogStats message for testing. -func mockLogStats(originalSQL string) *tabletenv.LogStats { - logstats := tabletenv.NewLogStats(context.Background(), "Execute") +func mockLogStats(originalSQL string, redactUIQuery bool) *tabletenv.LogStats { + logstats := tabletenv.NewLogStats(context.Background(), "Execute", streamlog.NewQueryLogConfigForTest()) logstats.StartTime = time.Time{} logstats.PlanType = "PASS_SELECT" logstats.OriginalSQL = originalSQL logstats.AddRewrittenSQL(originalSQL, time.Now()) logstats.MysqlResponseTime = 0 + logstats.Config.RedactDebugUIQueries = redactUIQuery return logstats } @@ -112,11 +113,11 @@ func TestSyslog(t *testing.T) { }() // Send fake messages to the mock channel, and then close the channel to end the plugin loop - ch <- mockLogStats("select 1") - ch <- mockLogStats("select 2") - ch <- mockLogStats("select 3") - ch <- mockLogStats("select 4") - ch <- mockLogStats("select 5") + ch <- mockLogStats("select 1", false) + ch <- mockLogStats("select 2", false) + ch <- mockLogStats("select 3", false) + ch <- mockLogStats("select 4", false) + ch <- mockLogStats("select 5", false) close(ch) <-syncChannel @@ -142,10 +143,6 @@ func TestSyslog(t *testing.T) { // when redaction is enabled. func TestSyslogRedacted(t *testing.T) { // Overwrite the usual syslog writer and StatsLogger subscription channel with mocks - streamlog.SetRedactDebugUIQueries(true) - defer func() { - streamlog.SetRedactDebugUIQueries(false) - }() mock := newFakeWriter() writer = mock ch = make(chan *tabletenv.LogStats, 10) @@ -158,11 +155,11 @@ func TestSyslogRedacted(t *testing.T) { }() // Send fake messages to the mock channel, and then close the channel to end the plugin loop - ch <- mockLogStats("select 1") - ch <- mockLogStats("select 2") - ch <- mockLogStats("select 3") - ch <- mockLogStats("select 4") - ch <- mockLogStats("select 5") + ch <- mockLogStats("select 1", true) + ch <- mockLogStats("select 2", true) + ch <- mockLogStats("select 3", true) + ch <- mockLogStats("select 4", true) + ch <- mockLogStats("select 5", true) close(ch) <-syncChannel @@ -198,10 +195,10 @@ func TestSyslogWithBadData(t *testing.T) { }() // Send 5 records for logging, one of which is bad - ch <- mockLogStats("select 1") - ch <- mockLogStats("select 2") - ch <- mockLogStats("select 3") - ch <- mockLogStats("select 5") + ch <- mockLogStats("select 1", false) + ch <- mockLogStats("select 2", false) + ch <- mockLogStats("select 3", false) + ch <- mockLogStats("select 5", false) close(ch) <-syncChannel @@ -239,11 +236,11 @@ func TestSyslogWithInterruptedConnection(t *testing.T) { close(syncChannel) }() - ch <- mockLogStats("select 1") - ch <- mockLogStats("select 2") - ch <- mockLogStats("select 3") - ch <- mockLogStats("select 4") // This record will get dropped due to a syslog outage - ch <- mockLogStats("select 5") + ch <- mockLogStats("select 1", false) + ch <- mockLogStats("select 2", false) + ch <- mockLogStats("select 3", false) + ch <- mockLogStats("select 4", false) // This record will get dropped due to a syslog outage + ch <- mockLogStats("select 5", false) close(ch) <-syncChannel diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index 2d62b017433..e63cd028d05 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -702,7 +702,8 @@ func (f *FakeQueryService) StreamHealth(ctx context.Context, callback func(*quer // VStream is part of the queryservice.QueryService interface func (f *FakeQueryService) VStream(ctx context.Context, request *binlogdatapb.VStreamRequest, send func([]*binlogdatapb.VEvent) error) error { - panic("not implemented") + // This is called as part of vreplication unit tests, so we don't panic here. + return fmt.Errorf("VStream not implemented") } // VStreamRows is part of the QueryService interface. diff --git a/go/vt/vttablet/tabletmanager/framework_test.go b/go/vt/vttablet/tabletmanager/framework_test.go index 35aa7a08b46..8e03f73bf79 100644 --- a/go/vt/vttablet/tabletmanager/framework_test.go +++ b/go/vt/vttablet/tabletmanager/framework_test.go @@ -399,6 +399,8 @@ type fakeTMClient struct { getSchemaCounts map[string]int // Used to confirm the number of times WorkflowDelete was called. workflowDeleteCalls int + // Used to confirm the number of times UpdateVReplicationWorkflow with state as Stopped was called. + workflowStopCalls int } func newFakeTMClient() *fakeTMClient { @@ -580,5 +582,8 @@ func (tmc *fakeTMClient) ReadVReplicationWorkflows(ctx context.Context, tablet * func (tmc *fakeTMClient) UpdateVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.UpdateVReplicationWorkflowRequest) (*tabletmanagerdatapb.UpdateVReplicationWorkflowResponse, error) { tmc.mu.Lock() defer tmc.mu.Unlock() + if *req.State == binlogdatapb.VReplicationWorkflowState_Stopped { + tmc.workflowStopCalls++ + } return tmc.tablets[int(tablet.Alias.Uid)].tm.UpdateVReplicationWorkflow(ctx, req) } diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 35587124108..54813e11bf3 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -19,7 +19,6 @@ package tabletmanager import ( "context" "fmt" - "io" "time" "github.com/spf13/pflag" @@ -29,22 +28,17 @@ import ( "vitess.io/vitess/go/stats" - "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/hook" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/mysqlctl/backupstats" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/proto/vttime" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" ) // This file handles the initial backup restore upon startup. @@ -80,31 +74,6 @@ func registerIncrementalRestoreFlags(fs *pflag.FlagSet) { fs.StringVar(&restoreToPos, "restore-to-pos", restoreToPos, "(init incremental restore parameter) if set, run a point in time recovery that ends with the given position. This will attempt to use one full backup followed by zero or more incremental backups") } -var ( - // Flags for PITR - old iteration - binlogHost string - binlogPort int - binlogUser string - binlogPwd string - timeoutForGTIDLookup = 60 * time.Second - binlogSslCa string - binlogSslCert string - binlogSslKey string - binlogSslServerName string -) - -func registerPointInTimeRestoreFlags(fs *pflag.FlagSet) { - fs.StringVar(&binlogHost, "binlog_host", binlogHost, "PITR restore parameter: hostname/IP of binlog server.") - fs.IntVar(&binlogPort, "binlog_port", binlogPort, "PITR restore parameter: port of binlog server.") - fs.StringVar(&binlogUser, "binlog_user", binlogUser, "PITR restore parameter: username of binlog server.") - fs.StringVar(&binlogPwd, "binlog_password", binlogPwd, "PITR restore parameter: password of binlog server.") - fs.DurationVar(&timeoutForGTIDLookup, "pitr_gtid_lookup_timeout", timeoutForGTIDLookup, "PITR restore parameter: timeout for fetching gtid from timestamp.") - fs.StringVar(&binlogSslCa, "binlog_ssl_ca", binlogSslCa, "PITR restore parameter: Filename containing TLS CA certificate to verify binlog server TLS certificate against.") - fs.StringVar(&binlogSslCert, "binlog_ssl_cert", binlogSslCert, "PITR restore parameter: Filename containing mTLS client certificate to present to binlog server as authentication.") - fs.StringVar(&binlogSslKey, "binlog_ssl_key", binlogSslKey, "PITR restore parameter: Filename containing mTLS client private key for use in binlog server authentication.") - fs.StringVar(&binlogSslServerName, "binlog_ssl_server_name", binlogSslServerName, "PITR restore parameter: TLS server name (common name) to verify against for the binlog server we are connecting to (If not set: use the hostname or IP supplied in --binlog_host).") -} - func init() { servenv.OnParseFor("vtcombo", registerRestoreFlags) servenv.OnParseFor("vttablet", registerRestoreFlags) @@ -112,9 +81,6 @@ func init() { servenv.OnParseFor("vtcombo", registerIncrementalRestoreFlags) servenv.OnParseFor("vttablet", registerIncrementalRestoreFlags) - servenv.OnParseFor("vtcombo", registerPointInTimeRestoreFlags) - servenv.OnParseFor("vttablet", registerPointInTimeRestoreFlags) - statsRestoreBackupTime = stats.NewString("RestoredBackupTime") statsRestoreBackupPosition = stats.NewString("RestorePosition") } @@ -299,15 +265,6 @@ func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.L pos = backupManifest.Position params.Logger.Infof("Restore: pos=%v", replication.EncodePosition(pos)) } - // If SnapshotTime is set , then apply the incremental change - if keyspaceInfo.SnapshotTime != nil { - params.Logger.Infof("Restore: Restoring to time %v from binlog", keyspaceInfo.SnapshotTime) - err = tm.restoreToTimeFromBinlog(ctx, pos, keyspaceInfo.SnapshotTime) - if err != nil { - log.Errorf("unable to restore to the specified time %s, error : %v", keyspaceInfo.SnapshotTime.String(), err) - return nil - } - } switch { case err == nil && backupManifest != nil: // Starting from here we won't be able to recover if we get stopped by a cancelled @@ -365,196 +322,6 @@ func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.L return tm.tmState.ChangeTabletType(bgCtx, originalType, DBActionNone) } -// restoreToTimeFromBinlog restores to the snapshot time of the keyspace -// currently this works with mysql based database only (as it uses mysql specific queries for restoring) -func (tm *TabletManager) restoreToTimeFromBinlog(ctx context.Context, pos replication.Position, restoreTime *vttime.Time) error { - // validate the minimal settings necessary for connecting to binlog server - if binlogHost == "" || binlogPort <= 0 || binlogUser == "" { - log.Warning("invalid binlog server setting, restoring to last available backup.") - return nil - } - - timeoutCtx, cancelFnc := context.WithTimeout(ctx, timeoutForGTIDLookup) - defer cancelFnc() - - afterGTIDPos, beforeGTIDPos, err := tm.getGTIDFromTimestamp(timeoutCtx, pos, restoreTime.Seconds) - if err != nil { - return err - } - - if afterGTIDPos == "" && beforeGTIDPos == "" { - return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, fmt.Sprintf("unable to fetch the GTID for the specified time - %s", restoreTime.String())) - } else if afterGTIDPos == "" && beforeGTIDPos != "" { - log.Info("no afterGTIDPos found, which implies we reached the end of all GTID events") - } - - log.Infof("going to restore upto the GTID - %s", afterGTIDPos) - // when we don't have before GTID, we will take it as current backup pos's last GTID - // this is case where someone tries to restore just to the 1st event after backup - if beforeGTIDPos == "" { - beforeGTIDPos = pos.GTIDSet.Last() - } - err = tm.catchupToGTID(timeoutCtx, afterGTIDPos, beforeGTIDPos) - if err != nil { - return vterrors.Wrapf(err, "unable to replicate upto desired GTID : %s", afterGTIDPos) - } - - return nil -} - -// getGTIDFromTimestamp computes 2 GTIDs based on restoreTime -// afterPos is the GTID of the first event at or after restoreTime. -// beforePos is the GTID of the last event before restoreTime. This is the GTID upto which replication will be applied -// afterPos can be used directly in the query `START SLAVE UNTIL SQL_BEFORE_GTIDS = ”` -// beforePos will be used to check if replication was able to catch up from the binlog server -func (tm *TabletManager) getGTIDFromTimestamp(ctx context.Context, pos replication.Position, restoreTime int64) (afterPos string, beforePos string, err error) { - connParams := &mysql.ConnParams{ - Host: binlogHost, - Port: binlogPort, - Uname: binlogUser, - SslCa: binlogSslCa, - SslCert: binlogSslCert, - SslKey: binlogSslKey, - ServerName: binlogSslServerName, - } - if binlogPwd != "" { - connParams.Pass = binlogPwd - } - if binlogSslCa != "" || binlogSslCert != "" { - connParams.EnableSSL() - } - dbCfgs := &dbconfigs.DBConfigs{ - Host: connParams.Host, - Port: connParams.Port, - } - dbCfgs.SetDbParams(*connParams, *connParams, *connParams) - vsClient := vreplication.NewReplicaConnector(tm.Env, connParams) - - filter := &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*", - }}, - } - - // get current lastPos of binlog server, so that if we hit that in vstream, we'll return from there - binlogConn, err := mysql.Connect(ctx, connParams) - if err != nil { - return "", "", err - } - defer binlogConn.Close() - lastPos, err := binlogConn.PrimaryPosition() - if err != nil { - return "", "", err - } - - gtidsChan := make(chan []string, 1) - - go func() { - err := vsClient.VStream(ctx, replication.EncodePosition(pos), filter, func(events []*binlogdatapb.VEvent) error { - for _, event := range events { - if event.Gtid != "" { - // check if we reached the lastPos then return - eventPos, err := replication.DecodePosition(event.Gtid) - if err != nil { - return err - } - - if event.Timestamp >= restoreTime { - afterPos = event.Gtid - gtidsChan <- []string{event.Gtid, beforePos} - return io.EOF - } - - if eventPos.AtLeast(lastPos) { - gtidsChan <- []string{"", beforePos} - return io.EOF - } - beforePos = event.Gtid - } - } - return nil - }) - if err != nil && err != io.EOF { - log.Warningf("Error using VStream to find timestamp for GTID position: %v error: %v", pos, err) - gtidsChan <- []string{"", ""} - } - }() - defer vsClient.Close() - select { - case val := <-gtidsChan: - return val[0], val[1], nil - case <-ctx.Done(): - log.Warningf("Can't find the GTID from restore time stamp, exiting.") - return "", beforePos, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "unable to find GTID from the snapshot time as context timed out") - } -} - -// catchupToGTID replicates upto specified GTID from binlog server -// -// copies the data from binlog server by pointing to as replica -// waits till all events to GTID replicated -// once done, it will reset the replication -func (tm *TabletManager) catchupToGTID(ctx context.Context, afterGTIDPos string, beforeGTIDPos string) error { - var afterGTID replication.Position - if afterGTIDPos != "" { - var err error - afterGTID, err = replication.DecodePosition(afterGTIDPos) - if err != nil { - return err - } - } - - beforeGTIDPosParsed, err := replication.DecodePosition(beforeGTIDPos) - if err != nil { - return err - } - - if err := tm.MysqlDaemon.CatchupToGTID(ctx, afterGTID); err != nil { - return vterrors.Wrap(err, fmt.Sprintf("failed to restart the replication until %s GTID", afterGTID.GTIDSet.Last())) - } - log.Infof("Waiting for position to reach", beforeGTIDPosParsed.GTIDSet.Last()) - // Could not use `agent.MysqlDaemon.WaitSourcePos` as replication is stopped with `START REPLICA UNTIL SQL_BEFORE_GTIDS` - // this is as per https://dev.mysql.com/doc/refman/8.0/en/start-replica.html - // We need to wait until replication catches upto the specified afterGTIDPos - chGTIDCaughtup := make(chan bool) - go func() { - timeToWait := time.Now().Add(timeoutForGTIDLookup) - for time.Now().Before(timeToWait) { - pos, err := tm.MysqlDaemon.PrimaryPosition(ctx) - if err != nil { - chGTIDCaughtup <- false - } - - if pos.AtLeast(beforeGTIDPosParsed) { - chGTIDCaughtup <- true - } - select { - case <-ctx.Done(): - chGTIDCaughtup <- false - default: - time.Sleep(300 * time.Millisecond) - } - } - }() - select { - case resp := <-chGTIDCaughtup: - if resp { - if err := tm.MysqlDaemon.StopReplication(ctx, nil); err != nil { - return vterrors.Wrap(err, "failed to stop replication") - } - if err := tm.MysqlDaemon.ResetReplicationParameters(ctx); err != nil { - return vterrors.Wrap(err, "failed to reset replication") - } - - return nil - } - return vterrors.Wrap(err, "error while fetching the current GTID position") - case <-ctx.Done(): - log.Warningf("Could not copy up to GTID.") - return vterrors.Wrapf(err, "context timeout while restoring up to specified GTID - %s", beforeGTIDPos) - } -} - // disableReplication stops and resets replication on the mysql server. It moreover sets impossible replication // source params, so that the replica can't possibly reconnect. It would take a `CHANGE [MASTER|REPLICATION SOURCE] TO ...` to // make the mysql server replicate again (available via tm.MysqlDaemon.SetReplicationPosition) diff --git a/go/vt/vttablet/tabletmanager/rpc_backup.go b/go/vt/vttablet/tabletmanager/rpc_backup.go index 22fe72716dd..9f906317edf 100644 --- a/go/vt/vttablet/tabletmanager/rpc_backup.go +++ b/go/vt/vttablet/tabletmanager/rpc_backup.go @@ -22,7 +22,7 @@ import ( "time" "vitess.io/vitess/go/vt/topotools" - "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl" @@ -136,12 +136,12 @@ func (tm *TabletManager) Backup(ctx context.Context, logger logutil.Logger, req l.Errorf("Failed to get durability policy, error: %v", err) return } - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { l.Errorf("Failed to get durability with name %v, error: %v", durabilityName, err) } - isSemiSync := reparentutil.IsReplicaSemiSync(durability, shardPrimary.Tablet, tabletInfo.Tablet) + isSemiSync := policy.IsReplicaSemiSync(durability, shardPrimary.Tablet, tabletInfo.Tablet) semiSyncAction, err := tm.convertBoolToSemiSyncAction(bgCtx, isSemiSync) if err != nil { l.Errorf("Failed to convert bool to semisync action, error: %v", err) diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 90e4d835a79..dec94ee6f16 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -19,6 +19,7 @@ package tabletmanager import ( "context" "fmt" + "runtime" "strings" "time" @@ -29,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tabletserver" @@ -46,7 +48,11 @@ func (tm *TabletManager) ReplicationStatus(ctx context.Context) (*replicationdat if err != nil { return nil, err } - return replication.ReplicationStatusToProto(status), nil + + protoStatus := replication.ReplicationStatusToProto(status) + protoStatus.BackupRunning = tm.IsBackupRunning() + + return protoStatus, nil } // FullStatus returns the full status of MySQL including the replication information, semi-sync information, GTID information among others @@ -54,6 +60,16 @@ func (tm *TabletManager) FullStatus(ctx context.Context) (*replicationdatapb.Ful if err := tm.waitForGrantsToHaveApplied(ctx); err != nil { return nil, err } + + // Return if the disk is stalled or rejecting writes. + // If the disk is stalled, we can't be sure if reads will go through + // or not, so we should not run any reads either. + if tm.QueryServiceControl.IsDiskStalled() { + return &replicationdatapb.FullStatus{ + DiskStalled: true, + }, nil + } + // Server ID - "select @@global.server_id" serverID, err := tm.MysqlDaemon.GetServerID(ctx) if err != nil { @@ -520,6 +536,23 @@ func (tm *TabletManager) demotePrimary(ctx context.Context, revertPartialFailure } defer tm.unlock() + finishCtx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + select { + case <-finishCtx.Done(): + // Finished running DemotePrimary. Nothing to do. + case <-time.After(10 * topo.RemoteOperationTimeout): + // We waited for over 10 times of remote operation timeout, but DemotePrimary is still not done. + // Collect more information and signal demote primary is indefinitely stalled. + log.Errorf("DemotePrimary seems to be stalled. Collecting more information.") + tm.QueryServiceControl.SetDemotePrimaryStalled() + buf := make([]byte, 1<<16) // 64 KB buffer size + stackSize := runtime.Stack(buf, true) + log.Errorf("Stack trace:\n%s", string(buf[:stackSize])) + } + }() + tablet := tm.Tablet() wasPrimary := tablet.Type == topodatapb.TabletType_PRIMARY wasServing := tm.QueryServiceControl.IsServing() @@ -893,6 +926,7 @@ func (tm *TabletManager) StopReplicationAndGetStatus(ctx context.Context, stopRe return StopReplicationAndGetStatusResponse{}, vterrors.Wrap(err, "before status failed") } before := replication.ReplicationStatusToProto(rs) + before.BackupRunning = tm.IsBackupRunning() if stopReplicationMode == replicationdatapb.StopReplicationMode_IOTHREADONLY { if !rs.IOHealthy() { @@ -939,6 +973,7 @@ func (tm *TabletManager) StopReplicationAndGetStatus(ctx context.Context, stopRe }, vterrors.Wrap(err, "acquiring replication status failed") } after := replication.ReplicationStatusToProto(rsAfter) + after.BackupRunning = tm.IsBackupRunning() rs.Position = rsAfter.Position rs.RelayLogPosition = rsAfter.RelayLogPosition diff --git a/go/vt/vttablet/tabletmanager/rpc_replication_test.go b/go/vt/vttablet/tabletmanager/rpc_replication_test.go index c587f1e24b8..b388235811b 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication_test.go @@ -18,10 +18,15 @@ package tabletmanager import ( "context" + "sync/atomic" "testing" "time" "github.com/stretchr/testify/require" + "golang.org/x/sync/semaphore" + + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vttablet/tabletserver" ) // TestWaitForGrantsToHaveApplied tests that waitForGrantsToHaveApplied only succeeds after waitForDBAGrants has been called. @@ -42,3 +47,49 @@ func TestWaitForGrantsToHaveApplied(t *testing.T) { err = tm.waitForGrantsToHaveApplied(secondContext) require.NoError(t, err) } + +type demotePrimaryStallQS struct { + tabletserver.Controller + waitTime time.Duration + primaryStalled atomic.Bool +} + +func (d *demotePrimaryStallQS) SetDemotePrimaryStalled() { + d.primaryStalled.Store(true) +} + +func (d *demotePrimaryStallQS) IsServing() bool { + time.Sleep(d.waitTime) + return false +} + +// TestDemotePrimaryStalled checks that if demote primary takes too long, then we mark it as stalled. +func TestDemotePrimaryStalled(t *testing.T) { + // Set remote operation timeout to a very low value. + origVal := topo.RemoteOperationTimeout + topo.RemoteOperationTimeout = 100 * time.Millisecond + defer func() { + topo.RemoteOperationTimeout = origVal + }() + + // Create a fake query service control to intercept calls from DemotePrimary function. + qsc := &demotePrimaryStallQS{ + waitTime: 2 * time.Second, + } + // Create a tablet manager with a replica type tablet. + tm := &TabletManager{ + actionSema: semaphore.NewWeighted(1), + MysqlDaemon: newTestMysqlDaemon(t, 1), + tmState: &tmState{ + displayState: displayState{ + tablet: newTestTablet(t, 100, "ks", "-", map[string]string{}), + }, + }, + QueryServiceControl: qsc, + } + + // We make IsServing stall for over 2 seconds, which is longer than 10 * remote operation timeout. + // This should cause the demote primary operation to be stalled. + tm.demotePrimary(context.Background(), false) + require.True(t, qsc.primaryStalled.Load()) +} diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication.go b/go/vt/vttablet/tabletmanager/rpc_vreplication.go index 8ddf1391ac4..522128cbf60 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication.go @@ -61,7 +61,7 @@ const ( // Retrieve the current configuration values for a workflow's vreplication stream(s). sqlSelectVReplicationWorkflowConfig = "select id, source, cell, tablet_types, state, message from %s.vreplication where workflow = %a" // Update the configuration values for a workflow's vreplication stream. - sqlUpdateVReplicationWorkflowStreamConfig = "update %s.vreplication set state = %a, source = %a, cell = %a, tablet_types = %a %s where id = %a" + sqlUpdateVReplicationWorkflowStreamConfig = "update %s.vreplication set state = %a, source = %a, cell = %a, tablet_types = %a, message = %a %s where id = %a" // Update field values for multiple workflows. The final format specifier is // used to optionally add any additional predicates to the query. sqlUpdateVReplicationWorkflows = "update /*vt+ ALLOW_UNSAFE_VREPLICATION_WRITE */ %s.vreplication set%s where db_name = '%s'%s" @@ -568,6 +568,9 @@ func (tm *TabletManager) UpdateVReplicationWorkflow(ctx context.Context, req *ta if !textutil.ValueIsSimulatedNull(req.TabletTypes) { tabletTypes = req.TabletTypes } + if req.Message != nil { + message = *req.Message + } tabletTypesStr := topoproto.MakeStringTypeCSV(tabletTypes) if req.TabletSelectionPreference != nil && ((inorder && *req.TabletSelectionPreference == tabletmanagerdatapb.TabletSelectionPreference_UNKNOWN) || @@ -609,9 +612,10 @@ func (tm *TabletManager) UpdateVReplicationWorkflow(ctx context.Context, req *ta "sc": sqltypes.StringBindVariable(string(source)), "cl": sqltypes.StringBindVariable(strings.Join(cells, ",")), "tt": sqltypes.StringBindVariable(tabletTypesStr), + "ms": sqltypes.StringBindVariable(message), "id": sqltypes.Int64BindVariable(id), } - parsed = sqlparser.BuildParsedQuery(sqlUpdateVReplicationWorkflowStreamConfig, sidecar.GetIdentifier(), ":st", ":sc", ":cl", ":tt", options, ":id") + parsed = sqlparser.BuildParsedQuery(sqlUpdateVReplicationWorkflowStreamConfig, sidecar.GetIdentifier(), ":st", ":sc", ":cl", ":tt", ":ms", options, ":id") stmt, err = parsed.GenerateQuery(bindVars, nil) if err != nil { return nil, err diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go index 0a5bd9f26fd..8f4b230104f 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go @@ -45,6 +45,7 @@ import ( "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vtgate/vindexes" vttablet "vitess.io/vitess/go/vt/vttablet/common" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" @@ -80,7 +81,7 @@ const ( readWorkflowsLimited = "select workflow, 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, options from _vt.vreplication where db_name = '%s' and workflow in ('%s') group by workflow, id order by workflow, id" readWorkflow = "select 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, options from _vt.vreplication where workflow = '%s' and db_name = '%s'" readWorkflowConfig = "select id, source, cell, tablet_types, state, message from _vt.vreplication where workflow = '%s'" - updateWorkflow = "update _vt.vreplication set state = '%s', source = '%s', cell = '%s', tablet_types = '%s' where id in (%d)" + updateWorkflow = "update _vt.vreplication set state = '%s', source = '%s', cell = '%s', tablet_types = '%s', message = '%s' where id in (%d)" getNonEmptyTableQuery = "select 1 from `%s` limit 1" ) @@ -305,7 +306,6 @@ func TestCreateVReplicationWorkflow(t *testing.T) { // results returned. Followed by ensuring that SwitchTraffic // and ReverseTraffic also work as expected. func TestMoveTablesUnsharded(t *testing.T) { - t.Skip("Skipping test temporarily as it is flaky on CI, pending investigation") ctx, cancel := context.WithCancel(context.Background()) defer cancel() sourceKs := "sourceks" @@ -335,31 +335,37 @@ func TestMoveTablesUnsharded(t *testing.T) { globalTablet := tenv.addTablet(t, 500, globalKs, globalShard) defer tenv.deleteTablet(globalTablet.tablet) - err := tenv.ts.SaveVSchema(ctx, globalKs, &vschemapb.Keyspace{ - Sharded: false, - Tables: map[string]*vschemapb.Table{ - "t1_seq": { - Type: vindexes.TypeSequence, + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: globalKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + Tables: map[string]*vschemapb.Table{ + "t1_seq": { + Type: vindexes.TypeSequence, + }, }, }, }) require.NoError(t, err) - err = tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "hash": { - Type: "hash", + err = tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "hash": { + Type: "hash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, - AutoIncrement: &vschemapb.AutoIncrement{ - Column: "id", - Sequence: "t1_seq", + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + AutoIncrement: &vschemapb.AutoIncrement{ + Column: "id", + Sequence: "t1_seq", + }, }, }, }, @@ -403,6 +409,9 @@ func TestMoveTablesUnsharded(t *testing.T) { ftc.vrdbClient.AddInvariant(getCopyStateQuery, &sqltypes.Result{}) tenv.tmc.setVReplicationExecResults(ftc.tablet, getCopyState, &sqltypes.Result{}) ftc.vrdbClient.ExpectRequest(fmt.Sprintf(readAllWorkflows, tenv.dbName, ""), &sqltypes.Result{}, nil) + for _, table := range defaultSchema.TableDefinitions { + tenv.db.AddQuery(fmt.Sprintf(getNonEmptyTableQuery, table.Name), &sqltypes.Result{}) + } insert := fmt.Sprintf(`%s values ('%s', 'keyspace:"%s" shard:"%s" filter:{rules:{match:"t1" filter:"select * from t1"}}', '', 0, 0, '%s', 'primary,replica,rdonly', now(), 0, 'Stopped', '%s', %d, 0, 0, '{}')`, insertVReplicationPrefix, wf, sourceKs, sourceShard, tenv.cells[0], tenv.dbName, vreplID) ftc.vrdbClient.ExpectRequest(insert, &sqltypes.Result{InsertID: 1}, nil) @@ -437,7 +446,7 @@ func TestMoveTablesUnsharded(t *testing.T) { fmt.Sprintf("%d|%s|||Stopped|", vreplID, bls), ), nil) ftc.vrdbClient.ExpectRequest(idQuery, idRes, nil) - ftc.vrdbClient.ExpectRequest(fmt.Sprintf(updateWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String(), bls, "", "", vreplID), &sqltypes.Result{}, nil) + ftc.vrdbClient.ExpectRequest(fmt.Sprintf(updateWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String(), bls, "", "", "", vreplID), &sqltypes.Result{}, nil) ftc.vrdbClient.ExpectRequest(fmt.Sprintf(getVReplicationRecord, vreplID), sqltypes.MakeTestResult( sqltypes.MakeTestFields( @@ -595,31 +604,37 @@ func TestMoveTablesSharded(t *testing.T) { globalTablet := tenv.addTablet(t, 500, globalKs, globalShard) defer tenv.deleteTablet(globalTablet.tablet) - err := tenv.ts.SaveVSchema(ctx, globalKs, &vschemapb.Keyspace{ - Sharded: false, - Tables: map[string]*vschemapb.Table{ - "t1_seq": { - Type: vindexes.TypeSequence, + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: globalKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: false, + Tables: map[string]*vschemapb.Table{ + "t1_seq": { + Type: vindexes.TypeSequence, + }, }, }, }) require.NoError(t, err) - err = tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "hash": { - Type: "hash", + err = tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "hash": { + Type: "hash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, - AutoIncrement: &vschemapb.AutoIncrement{ - Column: "id", - Sequence: "t1_seq", + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + AutoIncrement: &vschemapb.AutoIncrement{ + Column: "id", + Sequence: "t1_seq", + }, }, }, }, @@ -700,7 +715,7 @@ func TestMoveTablesSharded(t *testing.T) { fmt.Sprintf("%d|%s|||Stopped|", vreplID, bls), ), nil) ftc.vrdbClient.ExpectRequest(idQuery, idRes, nil) - ftc.vrdbClient.ExpectRequest(fmt.Sprintf(updateWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String(), bls, "", "", vreplID), &sqltypes.Result{}, nil) + ftc.vrdbClient.ExpectRequest(fmt.Sprintf(updateWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String(), bls, "", "", "", vreplID), &sqltypes.Result{}, nil) ftc.vrdbClient.ExpectRequest(fmt.Sprintf(getVReplicationRecord, vreplID), sqltypes.MakeTestResult( sqltypes.MakeTestFields( @@ -890,6 +905,13 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { ), fmt.Sprintf("%d|%s|%s|%s|Running|", vreplID, blsStr, cells[0], tabletTypes[0]), ) + selectResNonEmptyMessage := sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "id|source|cell|tablet_types|state|message", + "int64|varchar|varchar|varchar|varchar|varbinary", + ), + fmt.Sprintf("%d|%s|%s|%s|Running|initial test message", vreplID, blsStr, cells[0], tabletTypes[0]), + ) idQuery, err := sqlparser.ParseAndBind("select id from _vt.vreplication where id = %a", sqltypes.Int64BindVariable(int64(vreplID))) @@ -911,10 +933,11 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { copying := sqltypes.MakeTestResult(copyStatusFields, "1") tests := []struct { - name string - request *tabletmanagerdatapb.UpdateVReplicationWorkflowRequest - query string - isCopying bool + name string + request *tabletmanagerdatapb.UpdateVReplicationWorkflowRequest + query string + isCopying bool + initiallyNonEmptyMessage bool }{ { name: "update cells", @@ -923,7 +946,7 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { Cells: []string{"zone2"}, // TabletTypes is an empty value, so the current value should be cleared }, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '', message = '' where id in (%d)`, keyspace, shard, "zone2", vreplID), }, { @@ -933,7 +956,7 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { Cells: []string{"zone3"}, TabletTypes: textutil.SimulatedNullTabletTypeSlice, // So keep the current value of replica }, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s', message = '' where id in (%d)`, keyspace, shard, "zone3", tabletTypes[0], vreplID), }, { @@ -943,9 +966,20 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { TabletSelectionPreference: &inOrder, TabletTypes: []topodatapb.TabletType{topodatapb.TabletType_RDONLY, topodatapb.TabletType_REPLICA}, }, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '', tablet_types = '%s' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '', tablet_types = '%s', message = '' where id in (%d)`, keyspace, shard, "in_order:rdonly,replica", vreplID), }, + { + name: "update tablet_types, initially non-empty message", + request: &tabletmanagerdatapb.UpdateVReplicationWorkflowRequest{ + Workflow: workflow, + TabletSelectionPreference: &inOrder, + TabletTypes: []topodatapb.TabletType{topodatapb.TabletType_RDONLY, topodatapb.TabletType_REPLICA}, + }, + initiallyNonEmptyMessage: true, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '', tablet_types = '%s', message = '%s' where id in (%d)`, + keyspace, shard, "in_order:rdonly,replica", "initial test message", vreplID), + }, { name: "update tablet_types, NULL cells", request: &tabletmanagerdatapb.UpdateVReplicationWorkflowRequest{ @@ -953,7 +987,7 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { Cells: textutil.SimulatedNullStringSlice, // So keep the current value of zone1 TabletTypes: []topodatapb.TabletType{topodatapb.TabletType_RDONLY}, }, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s', message = '' where id in (%d)`, keyspace, shard, cells[0], "rdonly", vreplID), }, { @@ -962,7 +996,7 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { Workflow: workflow, OnDdl: &exec, }, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}} on_ddl:%s', cell = '', tablet_types = '' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}} on_ddl:%s', cell = '', tablet_types = '', message = '' where id in (%d)`, keyspace, shard, binlogdatapb.OnDDLAction_EXEC.String(), vreplID), }, { @@ -973,7 +1007,7 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { TabletTypes: []topodatapb.TabletType{topodatapb.TabletType_RDONLY, topodatapb.TabletType_REPLICA, topodatapb.TabletType_PRIMARY}, OnDdl: &execIgnore, }, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}} on_ddl:%s', cell = '%s', tablet_types = '%s' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}} on_ddl:%s', cell = '%s', tablet_types = '%s', message = '' where id in (%d)`, keyspace, shard, binlogdatapb.OnDDLAction_EXEC_IGNORE.String(), "zone1,zone2,zone3", "rdonly,replica,primary", vreplID), }, { @@ -984,9 +1018,28 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { Cells: textutil.SimulatedNullStringSlice, TabletTypes: textutil.SimulatedNullTabletTypeSlice, }, - query: fmt.Sprintf(`update _vt.vreplication set state = '%s', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = '%s', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s', message = '' where id in (%d)`, binlogdatapb.VReplicationWorkflowState_Stopped.String(), keyspace, shard, cells[0], tabletTypes[0], vreplID), }, + { + name: "update message", + request: &tabletmanagerdatapb.UpdateVReplicationWorkflowRequest{ + Workflow: workflow, + Message: ptr.Of("test message"), + }, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '', tablet_types = '', message = '%s' where id in (%d)`, + keyspace, shard, "test message", vreplID), + }, + { + name: "update message, initially non-empty message", + request: &tabletmanagerdatapb.UpdateVReplicationWorkflowRequest{ + Workflow: workflow, + Message: ptr.Of("test message"), + }, + initiallyNonEmptyMessage: true, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '', tablet_types = '', message = '%s' where id in (%d)`, + keyspace, shard, "test message", vreplID), + }, { name: "update to running while copying", request: &tabletmanagerdatapb.UpdateVReplicationWorkflowRequest{ @@ -996,7 +1049,7 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { TabletTypes: textutil.SimulatedNullTabletTypeSlice, }, isCopying: true, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Copying', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s' where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Copying', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '%s', message = '' where id in (%d)`, keyspace, shard, cells[0], tabletTypes[0], vreplID), }, { @@ -1009,7 +1062,7 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { "password": "secret", }, }, - query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '', options = json_set(options, '$.config', json_object(), '$.config."password"', 'secret', '$.config."user"', 'admin') where id in (%d)`, + query: fmt.Sprintf(`update _vt.vreplication set state = 'Running', source = 'keyspace:"%s" shard:"%s" filter:{rules:{match:"corder" filter:"select * from corder"} rules:{match:"customer" filter:"select * from customer"}}', cell = '%s', tablet_types = '', message = '', options = json_set(options, '$.config', json_object(), '$.config."password"', 'secret', '$.config."user"', 'admin') where id in (%d)`, keyspace, shard, "zone2", vreplID), }, } @@ -1031,7 +1084,11 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { // These are the same for each RPC call. tenv.tmc.tablets[tabletUID].vrdbClient.ExpectRequest(fmt.Sprintf("use %s", sidecar.GetIdentifier()), &sqltypes.Result{}, nil) - tenv.tmc.tablets[tabletUID].vrdbClient.ExpectRequest(selectQuery, selectRes, nil) + if tt.initiallyNonEmptyMessage { + tenv.tmc.tablets[tabletUID].vrdbClient.ExpectRequest(selectQuery, selectResNonEmptyMessage, nil) + } else { + tenv.tmc.tablets[tabletUID].vrdbClient.ExpectRequest(selectQuery, selectRes, nil) + } if tt.request.State == nil || *tt.request.State == binlogdatapb.VReplicationWorkflowState_Running { tenv.tmc.tablets[tabletUID].vrdbClient.ExpectRequest(fmt.Sprintf("use %s", sidecar.GetIdentifier()), &sqltypes.Result{}, nil) if tt.isCopying { @@ -1199,36 +1256,42 @@ func TestSourceShardSelection(t *testing.T) { ws := workflow.NewServer(vtenv.NewTestEnv(), tenv.ts, tenv.tmc) - err := tenv.ts.SaveVSchema(ctx, sourceKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "hash": { - Type: "hash", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: sourceKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "hash": { + Type: "hash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + }, }, }, }) require.NoError(t, err) - err = tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "hash": { - Type: "hash", + err = tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "hash": { + Type: "hash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + }, }, }, }) @@ -1330,7 +1393,11 @@ func TestSourceShardSelection(t *testing.T) { tenv.tmc.SetSchema(tt.schema) if tt.vschema != nil { - err = tenv.ts.SaveVSchema(ctx, targetKs, tt.vschema) + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: tt.vschema, + } + err = tenv.ts.SaveVSchema(ctx, ksvs) require.NoError(t, err) } @@ -1518,7 +1585,7 @@ func TestFailedMoveTablesCreateCleanup(t *testing.T) { // Check that our vschema changes were also rolled back. vs2, err := tenv.ts.GetVSchema(ctx, targetKs) require.NoError(t, err, "failed to get target vschema") - require.Equal(t, vs, vs2, "expected vschema to be unchanged") + require.Equal(t, vs.Keyspace, vs2.Keyspace, "expected vschema to be unchanged; expected: %+v, got: %+v", vs.Keyspace, vs2.Keyspace) } // TestHasVReplicationWorkflows tests the simple RPC to be sure @@ -1780,7 +1847,15 @@ func addInvariants(dbClient *binlogplayer.MockDBClient, vreplID, sourceTabletUID "0", )) dbClient.AddInvariant(fmt.Sprintf(updatePickedSourceTablet, cell, sourceTabletUID, vreplID), &sqltypes.Result{}) - + dbClient.AddInvariant("update _vt.vreplication set state='Running', message='' where id=1", &sqltypes.Result{}) + dbClient.AddInvariant(vreplication.SqlMaxAllowedPacket, sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "max_allowed_packet", + "int64", + ), + "65536", + )) + dbClient.AddInvariant("update _vt.vreplication set message", &sqltypes.Result{}) } func addMaterializeSettingsTablesToSchema(ms *vtctldatapb.MaterializeSettings, tenv *testEnv, venv *vtenv.Environment) { @@ -1912,7 +1987,8 @@ func TestExternalizeLookupVindex(t *testing.T) { vrResponse *sqltypes.Result err string expectedVschema *vschemapb.Keyspace - expectDelete bool + expectStopped bool + expectDeleted bool }{ { request: &vtctldatapb.LookupVindexExternalizeRequest{ @@ -1934,7 +2010,7 @@ func TestExternalizeLookupVindex(t *testing.T) { }, }, }, - expectDelete: true, + expectStopped: true, }, { request: &vtctldatapb.LookupVindexExternalizeRequest{ @@ -1977,7 +2053,30 @@ func TestExternalizeLookupVindex(t *testing.T) { }, }, }, - expectDelete: true, + expectStopped: true, + }, + { + request: &vtctldatapb.LookupVindexExternalizeRequest{ + Name: "owned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + DeleteWorkflow: true, + }, + vrResponse: ownedRunning, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "owned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.owned_lookup", + "from": "c1", + "to": "c2", + }, + Owner: "t1", + }, + }, + }, + expectDeleted: true, }, { request: &vtctldatapb.LookupVindexExternalizeRequest{ @@ -2023,36 +2122,78 @@ func TestExternalizeLookupVindex(t *testing.T) { for _, tcase := range testcases { t.Run(tcase.request.Name, func(t *testing.T) { // Resave the source schema for every iteration. - err := tenv.ts.SaveVSchema(ctx, tcase.request.Keyspace, sourceVschema) + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: tcase.request.Keyspace, + Keyspace: sourceVschema, + } + err := tenv.ts.SaveVSchema(ctx, ksvs) require.NoError(t, err) err = tenv.ts.RebuildSrvVSchema(ctx, []string{tenv.cells[0]}) require.NoError(t, err) require.NotNil(t, tcase.request, "No request provided") + bls := fmt.Sprintf("keyspace:\"%s\" shard:\"%s\" filter:{rules:{match:\"t1\" filter:\"select * from t1\"}}", sourceKs, sourceShard) + + idQuery, err := sqlparser.ParseAndBind("select id from _vt.vreplication where id = %a", + sqltypes.Int64BindVariable(int64(vreplID))) + require.NoError(t, err) + idRes := sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "id", + "int64", + ), + fmt.Sprintf("%d", vreplID), + ) + + streamsResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|state|cell|tablet_types|source", + "int64|varchar|varchar|varchar|varchar"), + fmt.Sprintf("%d|%s|cell1|PRIMARY|keyspace:\"%s\" shard:\"%s\"", 1, binlogdatapb.VReplicationWorkflowState_Stopped.String(), sourceKs, sourceShard), + ) for _, targetTablet := range targetShards { targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflow, tcase.request.Name, tenv.dbName), tcase.vrResponse, nil) - if tcase.err == "" { + // Update queries are required only if the Vindex is owned. + if tcase.expectStopped && len(tcase.expectedVschema.Vindexes) > 0 && tcase.expectedVschema.Vindexes[tcase.request.Name].Owner != "" { + targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, tcase.request.Name), sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "id|source|cell|tablet_types|state|message", + "int64|blob|varchar|varchar|varchar|varchar", + ), + fmt.Sprintf("%d|%s||primary|Stopped|", vreplID, bls), + ), nil) + targetTablet.vrdbClient.ExpectRequest(idQuery, idRes, nil) + targetTablet.vrdbClient.ExpectRequest(`update _vt.vreplication set state = 'Stopped', source = 'keyspace:"sourceks" shard:"0" filter:{rules:{match:"t1" filter:"select * from t1"}}', cell = '', tablet_types = '', message = 'FROZEN' where id in (1)`, &sqltypes.Result{}, nil) + targetTablet.vrdbClient.ExpectRequest(`select * from _vt.vreplication where id = 1`, streamsResult, nil) + } + if tcase.expectDeleted { // We query the workflow again to build the status output when // it's successfully created. targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflow, tcase.request.Name, tenv.dbName), tcase.vrResponse, nil) } } + preWorkflowStopCalls := tenv.tmc.workflowStopCalls preWorkflowDeleteCalls := tenv.tmc.workflowDeleteCalls _, err = ws.LookupVindexExternalize(ctx, tcase.request) if tcase.err != "" { if err == nil || !strings.Contains(err.Error(), tcase.err) { - require.FailNow(t, "LookupVindexExternalize error", "ExternalizeVindex(%v) err: %v, must contain %v", tcase.request, err, tcase.err) + require.FailNow(t, "LookupVindexExternalize error", "LookupVindexExternalize(%v) err: %v, must contain %v", tcase.request, err, tcase.err) } return } require.NoError(t, err) + expectedWorkflowStopCalls := preWorkflowStopCalls + if tcase.expectStopped { + // We expect the RPC to be called on each target shard. + expectedWorkflowStopCalls = preWorkflowStopCalls + (len(targetShards)) + } expectedWorkflowDeleteCalls := preWorkflowDeleteCalls - if tcase.expectDelete { + if tcase.expectDeleted { // We expect the RPC to be called on each target shard. expectedWorkflowDeleteCalls = preWorkflowDeleteCalls + (len(targetShards)) } + require.Equal(t, expectedWorkflowStopCalls, tenv.tmc.workflowStopCalls) require.Equal(t, expectedWorkflowDeleteCalls, tenv.tmc.workflowDeleteCalls) aftervschema, err := tenv.ts.GetVSchema(ctx, ms.SourceKeyspace) @@ -2066,127 +2207,643 @@ func TestExternalizeLookupVindex(t *testing.T) { } } -func TestMaterializerOneToOne(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - sourceKs := "sourceks" - sourceTabletUID := 200 - targetKs := "targetks" - targetTabletUID := 300 - shard := "0" - wf := "testwf" - vtenv := vtenv.NewTestEnv() - tenv := newTestEnv(t, ctx, sourceKs, []string{shard}) - defer tenv.close() - - sourceTablet := tenv.addTablet(t, sourceTabletUID, sourceKs, shard) - defer tenv.deleteTablet(sourceTablet.tablet) - targetTablet := tenv.addTablet(t, targetTabletUID, targetKs, shard) - defer tenv.deleteTablet(targetTablet.tablet) - - ws := workflow.NewServer(vtenv, tenv.ts, tenv.tmc) - ms := &vtctldatapb.MaterializeSettings{ - Workflow: wf, - SourceKeyspace: sourceKs, - TargetKeyspace: targetKs, - TableSettings: []*vtctldatapb.TableMaterializeSettings{ - { - TargetTable: "t1", - SourceExpression: "select * from t1", - CreateDdl: "t1ddl", - }, - { - TargetTable: "t2", - SourceExpression: "select * from t3", - CreateDdl: "t2ddl", - }, - { - TargetTable: "t4", - SourceExpression: "", // empty - CreateDdl: "t4ddl", - }, - }, - Cell: tenv.cells[0], - TabletTypes: topoproto.MakeStringTypeCSV([]topodatapb.TabletType{ - topodatapb.TabletType_PRIMARY, - topodatapb.TabletType_RDONLY, - }), - } - - addMaterializeSettingsTablesToSchema(ms, tenv, vtenv) - - targetTablet.vrdbClient.AddInvariant(fmt.Sprintf("use %s", sidecar.GetIdentifier()), &sqltypes.Result{}) - targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readAllWorkflows, tenv.dbName, ""), &sqltypes.Result{}, nil) - for _, table := range ms.TableSettings { - tenv.db.AddQuery(fmt.Sprintf(getNonEmptyTableQuery, table.TargetTable), &sqltypes.Result{}) - } - - // This is our expected query, which will also short circuit - // the test with an error as at this point we've tested what - // we wanted to test. - insert := insertVReplicationPrefix + - fmt.Sprintf(` values ('%s', 'keyspace:"%s" shard:"%s" filter:{rules:{match:"t1" filter:"select * from t1"} rules:{match:"t2" filter:"select * from t3"} rules:{match:"t4"}}', '', 0, 0, '%s', 'primary,rdonly', now(), 0, 'Stopped', '%s', 0, 0, 0, '{}')`, - wf, sourceKs, shard, tenv.cells[0], tenv.dbName) - targetTablet.vrdbClient.ExpectRequest(insert, &sqltypes.Result{}, errShortCircuit) - - err := ws.Materialize(ctx, ms) - targetTablet.vrdbClient.Wait() - require.ErrorIs(t, err, errShortCircuit) -} - -func TestMaterializerManyToOne(t *testing.T) { +func TestInternalizeLookupVindex(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() sourceKs := "sourceks" + sourceShard := "0" sourceTabletUID := 200 - sourceShards := make(map[string]*fakeTabletConn) targetKs := "targetks" + targetShards := make(map[string]*fakeTabletConn) targetTabletUID := 300 - targetShard := "0" wf := "testwf" vreplID := 1 vtenv := vtenv.NewTestEnv() tenv := newTestEnv(t, ctx, sourceKs, []string{shard}) defer tenv.close() - sourceShards["-80"] = tenv.addTablet(t, sourceTabletUID, sourceKs, "-80") - defer tenv.deleteTablet(sourceShards["-80"].tablet) - sourceShards["80-"] = tenv.addTablet(t, sourceTabletUID+10, sourceKs, "80-") - defer tenv.deleteTablet(sourceShards["80-"].tablet) + sourceTablet := tenv.addTablet(t, sourceTabletUID, sourceKs, sourceShard) + defer tenv.deleteTablet(sourceTablet.tablet) - targetTablet := tenv.addTablet(t, targetTabletUID, targetKs, targetShard) - defer tenv.deleteTablet(targetTablet.tablet) + targetShards["-80"] = tenv.addTablet(t, targetTabletUID, targetKs, "-80") + defer tenv.deleteTablet(targetShards["-80"].tablet) + addInvariants(targetShards["-80"].vrdbClient, vreplID, sourceTabletUID, position, wf, tenv.cells[0]) + targetShards["80-"] = tenv.addTablet(t, targetTabletUID+10, targetKs, "80-") + defer tenv.deleteTablet(targetShards["80-"].tablet) + addInvariants(targetShards["80-"].vrdbClient, vreplID, sourceTabletUID, position, wf, tenv.cells[0]) ws := workflow.NewServer(vtenv, tenv.ts, tenv.tmc) ms := &vtctldatapb.MaterializeSettings{ - Workflow: wf, + // Keyspace where the vindex is created. SourceKeyspace: sourceKs, + // Keyspace where the lookup table and VReplication workflow is created. TargetKeyspace: targetKs, - TableSettings: []*vtctldatapb.TableMaterializeSettings{{ - TargetTable: "t1", - SourceExpression: "select * from t1", - CreateDdl: "t1ddl", - }, { - TargetTable: "t2", - SourceExpression: "select * from t3", - CreateDdl: "t2ddl", - }}, - Cell: tenv.cells[0], + Cell: tenv.cells[0], TabletTypes: topoproto.MakeStringTypeCSV([]topodatapb.TabletType{ topodatapb.TabletType_PRIMARY, topodatapb.TabletType_RDONLY, }), } - addMaterializeSettingsTablesToSchema(ms, tenv, vtenv) - targetTablet.vrdbClient.AddInvariant("update _vt.vreplication set message='no schema defined' where id=1", &sqltypes.Result{}) // If the first workflow controller progresses ... - targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readAllWorkflows, tenv.dbName, ""), &sqltypes.Result{}, nil) - for _, table := range ms.TableSettings { - tenv.db.AddQuery(fmt.Sprintf(getNonEmptyTableQuery, table.TargetTable), &sqltypes.Result{}) + sourceVschema := &vschemapb.Keyspace{ + Sharded: false, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, + "owned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.owned_lookup", + "from": "c1", + "to": "c2", + }, + Owner: "t1", + }, + "unowned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.unowned_lookup", + "from": "c1", + "to": "c2", + }, + }, + "unqualified_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "unqualified", + "from": "c1", + "to": "c2", + }, + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "xxhash", + Column: "col1", + }, { + Name: "owned_lookup", + Column: "col2", + }}, + }, + }, } - // This is our expected query, which will also short circuit - // the test with an error as at this point we've tested what + trxTS := fmt.Sprintf("%d", time.Now().Unix()) + fields := sqltypes.MakeTestFields( + "id|state|message|source|workflow_type|workflow_sub_type|max_tps|max_replication_lag|time_updated|time_heartbeat|time_throttled|transaction_timestamp|rows_copied|options", + "int64|varbinary|varbinary|blob|int64|int64|int64|int64|int64|int64|int64|int64|int64|varchar", + ) + wftype := fmt.Sprintf("%d", binlogdatapb.VReplicationWorkflowType_CreateLookupIndex) + ownedSourceStopAfterCopy := fmt.Sprintf(`keyspace:"%s",shard:"0",filter:{rules:{match:"owned_lookup" filter:"select * from t1 where in_keyrange(col1, '%s.xxhash', '-80')"}} stop_after_copy:true`, + ms.SourceKeyspace, ms.SourceKeyspace) + ownedSourceKeepRunningAfterCopy := fmt.Sprintf(`keyspace:"%s",shard:"0",filter:{rules:{match:"owned_lookup" filter:"select * from t1 where in_keyrange(col1, '%s.xxhash', '-80')"}}`, + ms.SourceKeyspace, ms.SourceKeyspace) + ownedRunning := sqltypes.MakeTestResult(fields, "1|Running|msg|"+ownedSourceKeepRunningAfterCopy+"|"+wftype+"|0|0|0|0|0|0|"+trxTS+"|5|{}") + ownedStopped := sqltypes.MakeTestResult(fields, "1|Stopped|"+workflow.Frozen+"|"+ownedSourceStopAfterCopy+"|"+wftype+"|0|0|0|0|0|0|"+trxTS+"|5|{}") + + testcases := []struct { + request *vtctldatapb.LookupVindexInternalizeRequest + vrResponse *sqltypes.Result + err string + expectedVschema *vschemapb.Keyspace + }{ + { + request: &vtctldatapb.LookupVindexInternalizeRequest{ + Name: "owned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + vrResponse: ownedStopped, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "owned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.owned_lookup", + "from": "c1", + "to": "c2", + "write_only": "true", + }, + Owner: "t1", + }, + }, + }, + }, + { + request: &vtctldatapb.LookupVindexInternalizeRequest{ + Name: "unowned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "unowned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.unowned_lookup", + "from": "c1", + "to": "c2", + }, + }, + }, + }, + err: "no owner", + }, + { + request: &vtctldatapb.LookupVindexInternalizeRequest{ + Name: "owned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + vrResponse: ownedRunning, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "owned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.owned_lookup", + "from": "c1", + "to": "c2", + "write_only": "true", + }, + Owner: "t1", + }, + }, + }, + err: "not frozen", + }, + { + request: &vtctldatapb.LookupVindexInternalizeRequest{ + Name: "unowned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "unowned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.unowned_lookup", + "from": "c1", + "to": "c2", + "write_only": "true", + }, + }, + }, + }, + err: "no owner", + }, + { + request: &vtctldatapb.LookupVindexInternalizeRequest{ + Name: "absent_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "absent_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.absent_lookup", + "from": "c1", + "to": "c2", + }, + }, + }, + }, + err: "vindex absent_lookup not found in the sourceks keyspace", + }, + } + for _, tcase := range testcases { + t.Run(tcase.request.Name, func(t *testing.T) { + // Resave the source schema for every iteration. + sourceKsVS := &topo.KeyspaceVSchemaInfo{ + Name: tcase.request.Keyspace, + Keyspace: sourceVschema, + } + err := tenv.ts.SaveVSchema(ctx, sourceKsVS) + require.NoError(t, err) + err = tenv.ts.RebuildSrvVSchema(ctx, []string{tenv.cells[0]}) + require.NoError(t, err) + + require.NotNil(t, tcase.request, "No request provided") + + for _, targetTablet := range targetShards { + if tcase.vrResponse != nil { + targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflow, tcase.request.Name, tenv.dbName), tcase.vrResponse, nil) + } + // Update queries are required only if the Vindex is owned. + if len(tcase.expectedVschema.Vindexes) > 0 && tcase.expectedVschema.Vindexes[tcase.request.Name].Owner != "" { + unfreezeQuery, err := sqlparser.ParseAndBind(workflow.SqlUnfreezeWorkflow, + sqltypes.StringBindVariable("vt_targetks"), + sqltypes.StringBindVariable(tcase.request.Name), + ) + require.NoError(t, err) + tenv.tmc.setVReplicationExecResults(targetTablet.tablet, unfreezeQuery, &sqltypes.Result{}) + } + } + + _, err = ws.LookupVindexInternalize(ctx, tcase.request) + if tcase.err != "" { + if err == nil || !strings.Contains(err.Error(), tcase.err) { + require.FailNow(t, "LookupVindexInternalize error", "LookupVindexInternalize(%v) err: %v, must contain %v", tcase.request, err, tcase.err) + } + return + } + require.NoError(t, err) + aftervschema, err := tenv.ts.GetVSchema(ctx, ms.SourceKeyspace) + require.NoError(t, err) + vindex := aftervschema.Vindexes[tcase.request.Name] + expectedVindex := tcase.expectedVschema.Vindexes[tcase.request.Name] + require.NotNil(t, vindex, "vindex %s not found in vschema", tcase.request.Name) + require.Equal(t, expectedVindex, vindex, "vindex mismatch. expected: %+v, got: %+v", expectedVindex, vindex) + }) + } +} + +func TestCompleteLookupVindex(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + sourceKs := "sourceks" + sourceShard := "0" + sourceTabletUID := 200 + targetKs := "targetks" + targetShards := make(map[string]*fakeTabletConn) + targetTabletUID := 300 + wf := "testwf" + vreplID := 1 + vtenv := vtenv.NewTestEnv() + tenv := newTestEnv(t, ctx, sourceKs, []string{shard}) + defer tenv.close() + + sourceTablet := tenv.addTablet(t, sourceTabletUID, sourceKs, sourceShard) + defer tenv.deleteTablet(sourceTablet.tablet) + + targetShards["-80"] = tenv.addTablet(t, targetTabletUID, targetKs, "-80") + defer tenv.deleteTablet(targetShards["-80"].tablet) + addInvariants(targetShards["-80"].vrdbClient, vreplID, sourceTabletUID, position, wf, tenv.cells[0]) + targetShards["80-"] = tenv.addTablet(t, targetTabletUID+10, targetKs, "80-") + defer tenv.deleteTablet(targetShards["80-"].tablet) + addInvariants(targetShards["80-"].vrdbClient, vreplID, sourceTabletUID, position, wf, tenv.cells[0]) + + ws := workflow.NewServer(vtenv, tenv.ts, tenv.tmc) + ms := &vtctldatapb.MaterializeSettings{ + // Keyspace where the vindex is created. + SourceKeyspace: sourceKs, + // Keyspace where the lookup table and VReplication workflow is created. + TargetKeyspace: targetKs, + Cell: tenv.cells[0], + TabletTypes: topoproto.MakeStringTypeCSV([]topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_RDONLY, + }), + } + + sourceVschema := &vschemapb.Keyspace{ + Sharded: false, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, + "owned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.owned_lookup", + "from": "c1", + "to": "c2", + }, + Owner: "t1", + }, + "unowned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.unowned_lookup", + "from": "c1", + "to": "c2", + }, + }, + "unqualified_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "unqualified", + "from": "c1", + "to": "c2", + }, + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "xxhash", + Column: "col1", + }, { + Name: "owned_lookup", + Column: "col2", + }}, + }, + }, + } + + trxTS := fmt.Sprintf("%d", time.Now().Unix()) + fields := sqltypes.MakeTestFields( + "id|state|message|source|workflow_type|workflow_sub_type|max_tps|max_replication_lag|time_updated|time_heartbeat|time_throttled|transaction_timestamp|rows_copied|options", + "int64|varbinary|varbinary|blob|int64|int64|int64|int64|int64|int64|int64|int64|int64|varchar", + ) + wftype := fmt.Sprintf("%d", binlogdatapb.VReplicationWorkflowType_CreateLookupIndex) + ownedSourceStopAfterCopy := fmt.Sprintf(`keyspace:"%s",shard:"0",filter:{rules:{match:"owned_lookup" filter:"select * from t1 where in_keyrange(col1, '%s.xxhash', '-80')"}} stop_after_copy:true`, + ms.SourceKeyspace, ms.SourceKeyspace) + ownedSourceKeepRunningAfterCopy := fmt.Sprintf(`keyspace:"%s",shard:"0",filter:{rules:{match:"owned_lookup" filter:"select * from t1 where in_keyrange(col1, '%s.xxhash', '-80')"}}`, + ms.SourceKeyspace, ms.SourceKeyspace) + ownedRunning := sqltypes.MakeTestResult(fields, "1|Running|msg|"+ownedSourceKeepRunningAfterCopy+"|"+wftype+"|0|0|0|0|0|0|"+trxTS+"|5|{}") + ownedStopped := sqltypes.MakeTestResult(fields, "1|Stopped|"+workflow.Frozen+"|"+ownedSourceStopAfterCopy+"|"+wftype+"|0|0|0|0|0|0|"+trxTS+"|5|{}") + + testcases := []struct { + request *vtctldatapb.LookupVindexCompleteRequest + vrResponse *sqltypes.Result + err string + expectedVschema *vschemapb.Keyspace + expectDelete bool + }{ + { + request: &vtctldatapb.LookupVindexCompleteRequest{ + Name: "owned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + vrResponse: ownedStopped, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "owned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.owned_lookup", + "from": "c1", + "to": "c2", + }, + Owner: "t1", + }, + }, + }, + expectDelete: true, + }, + { + request: &vtctldatapb.LookupVindexCompleteRequest{ + Name: "unowned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "unowned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.unowned_lookup", + "from": "c1", + "to": "c2", + }, + }, + }, + }, + err: "no owner", + }, + { + request: &vtctldatapb.LookupVindexCompleteRequest{ + Name: "owned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + vrResponse: ownedRunning, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "owned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.owned_lookup", + "from": "c1", + "to": "c2", + }, + Owner: "t1", + }, + }, + }, + err: "not frozen", + }, + { + request: &vtctldatapb.LookupVindexCompleteRequest{ + Name: "unowned_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "unowned_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.unowned_lookup", + "from": "c1", + "to": "c2", + }, + }, + }, + }, + err: "no owner", + }, + { + request: &vtctldatapb.LookupVindexCompleteRequest{ + Name: "absent_lookup", + Keyspace: ms.SourceKeyspace, + TableKeyspace: ms.TargetKeyspace, + }, + expectedVschema: &vschemapb.Keyspace{ + Vindexes: map[string]*vschemapb.Vindex{ + "absent_lookup": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "targetks.absent_lookup", + "from": "c1", + "to": "c2", + }, + }, + }, + }, + err: "vindex absent_lookup not found in the sourceks keyspace", + }, + } + for _, tcase := range testcases { + t.Run(tcase.request.Name, func(t *testing.T) { + // Resave the source schema for every iteration. + sourceKsVS := &topo.KeyspaceVSchemaInfo{ + Name: tcase.request.Keyspace, + Keyspace: sourceVschema, + } + err := tenv.ts.SaveVSchema(ctx, sourceKsVS) + require.NoError(t, err) + err = tenv.ts.RebuildSrvVSchema(ctx, []string{tenv.cells[0]}) + require.NoError(t, err) + + require.NotNil(t, tcase.request, "No request provided") + + for _, targetTablet := range targetShards { + if tcase.vrResponse != nil { + targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflow, tcase.request.Name, tenv.dbName), tcase.vrResponse, nil) + } + if tcase.err == "" { + // We query the workflow again to build the status output when + // it's successfully created. + targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflow, tcase.request.Name, tenv.dbName), tcase.vrResponse, nil) + } + } + + preWorkflowDeleteCalls := tenv.tmc.workflowDeleteCalls + _, err = ws.LookupVindexComplete(ctx, tcase.request) + if tcase.err != "" { + if err == nil || !strings.Contains(err.Error(), tcase.err) { + require.FailNow(t, "LookupVindexComplete error", "LookupVindexComplete(%v) err: %v, must contain %v", tcase.request, err, tcase.err) + } + return + } + require.NoError(t, err) + expectedWorkflowDeleteCalls := preWorkflowDeleteCalls + if tcase.expectDelete { + // We expect the RPC to be called on each target shard. + expectedWorkflowDeleteCalls = preWorkflowDeleteCalls + (len(targetShards)) + } + require.Equal(t, expectedWorkflowDeleteCalls, tenv.tmc.workflowDeleteCalls) + + aftervschema, err := tenv.ts.GetVSchema(ctx, ms.SourceKeyspace) + require.NoError(t, err) + vindex := aftervschema.Vindexes[tcase.request.Name] + expectedVindex := tcase.expectedVschema.Vindexes[tcase.request.Name] + require.NotNil(t, vindex, "vindex %s not found in vschema", tcase.request.Name) + require.NotContains(t, vindex.Params, "write_only", tcase.request) + require.Equal(t, expectedVindex, vindex, "vindex mismatch. expected: %+v, got: %+v", expectedVindex, vindex) + }) + } +} + +func TestMaterializerOneToOne(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + sourceKs := "sourceks" + sourceTabletUID := 200 + targetKs := "targetks" + targetTabletUID := 300 + shard := "0" + wf := "testwf" + vtenv := vtenv.NewTestEnv() + tenv := newTestEnv(t, ctx, sourceKs, []string{shard}) + defer tenv.close() + + sourceTablet := tenv.addTablet(t, sourceTabletUID, sourceKs, shard) + defer tenv.deleteTablet(sourceTablet.tablet) + targetTablet := tenv.addTablet(t, targetTabletUID, targetKs, shard) + defer tenv.deleteTablet(targetTablet.tablet) + + ws := workflow.NewServer(vtenv, tenv.ts, tenv.tmc) + ms := &vtctldatapb.MaterializeSettings{ + Workflow: wf, + SourceKeyspace: sourceKs, + TargetKeyspace: targetKs, + TableSettings: []*vtctldatapb.TableMaterializeSettings{ + { + TargetTable: "t1", + SourceExpression: "select * from t1", + CreateDdl: "t1ddl", + }, + { + TargetTable: "t2", + SourceExpression: "select * from t3", + CreateDdl: "t2ddl", + }, + { + TargetTable: "t4", + SourceExpression: "", // empty + CreateDdl: "t4ddl", + }, + }, + Cell: tenv.cells[0], + TabletTypes: topoproto.MakeStringTypeCSV([]topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_RDONLY, + }), + } + + addMaterializeSettingsTablesToSchema(ms, tenv, vtenv) + + targetTablet.vrdbClient.AddInvariant(fmt.Sprintf("use %s", sidecar.GetIdentifier()), &sqltypes.Result{}) + targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readAllWorkflows, tenv.dbName, ""), &sqltypes.Result{}, nil) + for _, table := range ms.TableSettings { + tenv.db.AddQuery(fmt.Sprintf(getNonEmptyTableQuery, table.TargetTable), &sqltypes.Result{}) + } + + // This is our expected query, which will also short circuit + // the test with an error as at this point we've tested what + // we wanted to test. + insert := insertVReplicationPrefix + + fmt.Sprintf(` values ('%s', 'keyspace:"%s" shard:"%s" filter:{rules:{match:"t1" filter:"select * from t1"} rules:{match:"t2" filter:"select * from t3"} rules:{match:"t4"}}', '', 0, 0, '%s', 'primary,rdonly', now(), 0, 'Stopped', '%s', 0, 0, 0, '{}')`, + wf, sourceKs, shard, tenv.cells[0], tenv.dbName) + targetTablet.vrdbClient.ExpectRequest(insert, &sqltypes.Result{}, errShortCircuit) + + err := ws.Materialize(ctx, ms) + targetTablet.vrdbClient.Wait() + require.ErrorIs(t, err, errShortCircuit) +} + +func TestMaterializerManyToOne(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + sourceKs := "sourceks" + sourceTabletUID := 200 + sourceShards := make(map[string]*fakeTabletConn) + targetKs := "targetks" + targetTabletUID := 300 + targetShard := "0" + wf := "testwf" + vreplID := 1 + vtenv := vtenv.NewTestEnv() + tenv := newTestEnv(t, ctx, sourceKs, []string{shard}) + defer tenv.close() + + sourceShards["-80"] = tenv.addTablet(t, sourceTabletUID, sourceKs, "-80") + defer tenv.deleteTablet(sourceShards["-80"].tablet) + sourceShards["80-"] = tenv.addTablet(t, sourceTabletUID+10, sourceKs, "80-") + defer tenv.deleteTablet(sourceShards["80-"].tablet) + + targetTablet := tenv.addTablet(t, targetTabletUID, targetKs, targetShard) + defer tenv.deleteTablet(targetTablet.tablet) + + ws := workflow.NewServer(vtenv, tenv.ts, tenv.tmc) + ms := &vtctldatapb.MaterializeSettings{ + Workflow: wf, + SourceKeyspace: sourceKs, + TargetKeyspace: targetKs, + TableSettings: []*vtctldatapb.TableMaterializeSettings{{ + TargetTable: "t1", + SourceExpression: "select * from t1", + CreateDdl: "t1ddl", + }, { + TargetTable: "t2", + SourceExpression: "select * from t3", + CreateDdl: "t2ddl", + }}, + Cell: tenv.cells[0], + TabletTypes: topoproto.MakeStringTypeCSV([]topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_RDONLY, + }), + } + + addMaterializeSettingsTablesToSchema(ms, tenv, vtenv) + targetTablet.vrdbClient.AddInvariant("update _vt.vreplication set message='no schema defined' where id=1", &sqltypes.Result{}) // If the first workflow controller progresses ... + targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readAllWorkflows, tenv.dbName, ""), &sqltypes.Result{}, nil) + for _, table := range ms.TableSettings { + tenv.db.AddQuery(fmt.Sprintf(getNonEmptyTableQuery, table.TargetTable), &sqltypes.Result{}) + } + + // This is our expected query, which will also short circuit + // the test with an error as at this point we've tested what // we wanted to test. for _, sourceShard := range []string{"-80", "80-"} { // One insert per [binlog]source/stream addInvariants(targetTablet.vrdbClient, vreplID, sourceTabletUID, position, wf, tenv.cells[0]) @@ -2264,19 +2921,22 @@ func TestMaterializerOneToMany(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "xxhash": { - Type: "xxhash", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "c1", - Name: "xxhash", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "c1", + Name: "xxhash", + }}, + }, }, }, }) @@ -2373,19 +3033,22 @@ func TestMaterializerManyToMany(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "xxhash": { - Type: "xxhash", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "c1", - Name: "xxhash", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "c1", + Name: "xxhash", + }}, + }, }, }, }) @@ -2483,22 +3146,25 @@ func TestMaterializerMulticolumnVindex(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "region": { - Type: "region_experimental", - Params: map[string]string{ - "region_bytes": "1", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "region": { + Type: "region_experimental", + Params: map[string]string{ + "region_bytes": "1", + }, }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Columns: []string{"c1", "c2"}, - Name: "region", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Columns: []string{"c1", "c2"}, + Name: "region", + }}, + }, }, }, }) @@ -2737,22 +3403,25 @@ func TestMaterializerExplicitColumns(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "region": { - Type: "region_experimental", - Params: map[string]string{ - "region_bytes": "1", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "region": { + Type: "region_experimental", + Params: map[string]string{ + "region_bytes": "1", + }, }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Columns: []string{"c1", "c2"}, - Name: "region", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Columns: []string{"c1", "c2"}, + Name: "region", + }}, + }, }, }, }) @@ -2847,22 +3516,25 @@ func TestMaterializerRenamedColumns(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "region": { - Type: "region_experimental", - Params: map[string]string{ - "region_bytes": "1", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "region": { + Type: "region_experimental", + Params: map[string]string{ + "region_bytes": "1", + }, }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Columns: []string{"c1", "c2"}, - Name: "region", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Columns: []string{"c1", "c2"}, + Name: "region", + }}, + }, }, }, }) @@ -3013,8 +3685,11 @@ func TestMaterializerNoTargetVSchema(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + }, }) require.NoError(t, err) @@ -3414,24 +4089,27 @@ func TestMaterializerNoGoodVindex(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "lookup_unique": { - Type: "lookup_unique", - Params: map[string]string{ - "table": "t1", - "from": "c1", - "to": "c2", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "lookup_unique": { + Type: "lookup_unique", + Params: map[string]string{ + "table": "t1", + "from": "c1", + "to": "c2", + }, }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "c1", - Name: "lookup_unique", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "c1", + Name: "lookup_unique", + }}, + }, }, }, }) @@ -3497,19 +4175,22 @@ func TestMaterializerComplexVindexExpression(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "xxhash": { - Type: "xxhash", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "c1", - Name: "xxhash", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "c1", + Name: "xxhash", + }}, + }, }, }, }) @@ -3575,19 +4256,22 @@ func TestMaterializerNoVindexInExpression(t *testing.T) { }), } - err := tenv.ts.SaveVSchema(ctx, targetKs, &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "xxhash": { - Type: "xxhash", + err := tenv.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "xxhash": { + Type: "xxhash", + }, }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "c1", - Name: "xxhash", - }}, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "c1", + Name: "xxhash", + }}, + }, }, }, }) diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index 84150c82be8..fbef04de357 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -70,7 +70,7 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" - "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tabletmanager/vdiff" @@ -1011,7 +1011,7 @@ func (tm *TabletManager) initializeReplication(ctx context.Context, tabletType t return "", vterrors.Wrapf(err, "cannot read keyspace durability policy %v", tablet.Keyspace) } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return "", vterrors.Wrapf(err, "cannot get durability policy %v", durabilityName) } @@ -1020,7 +1020,7 @@ func (tm *TabletManager) initializeReplication(ctx context.Context, tabletType t tablet.Type = tabletType - semiSyncAction, err := tm.convertBoolToSemiSyncAction(ctx, reparentutil.IsReplicaSemiSync(durability, currentPrimary.Tablet, tablet)) + semiSyncAction, err := tm.convertBoolToSemiSyncAction(ctx, policy.IsReplicaSemiSync(durability, currentPrimary.Tablet, tablet)) if err != nil { return "", err } diff --git a/go/vt/vttablet/tabletmanager/vdiff/engine_test.go b/go/vt/vttablet/tabletmanager/vdiff/engine_test.go index 61d713a8e58..374756418c6 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/engine_test.go @@ -139,7 +139,7 @@ func TestVDiff(t *testing.T) { "lastpk|mismatch|report", "varbinary|int64|json", ), - `fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}|0|{}`, + `target:{fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}}|0|{}`, ), nil) vdenv.dbClient.ExpectRequest(fmt.Sprintf("select column_name as column_name, collation_name as collation_name from information_schema.columns where table_schema='%s' and table_name='t1' and column_name in ('c1')", vdiffDBName), sqltypes.MakeTestResult(sqltypes.MakeTestFields( "collation_name", @@ -159,7 +159,7 @@ func TestVDiff(t *testing.T) { "lastpk|mismatch|report", "varbinary|int64|json", ), - `fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}|0|{"TableName": "t1", "MatchingRows": 1, "ProcessedRows": 1, "MismatchedRows": 0, "ExtraRowsSource": 0, "ExtraRowsTarget": 0}`, + `target:{fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}}|0|{}`, ), nil) vdenv.dbClient.ExpectRequest("update _vt.vdiff_table set table_rows = 1 where vdiff_id = 1 and table_name = 't1'", singleRowAffected, nil) @@ -169,7 +169,7 @@ func TestVDiff(t *testing.T) { "lastpk|mismatch|report", "varbinary|int64|json", ), - `fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}|0|{"TableName": "t1", "MatchingRows": 1, "ProcessedRows": 1, "MismatchedRows": 0, "ExtraRowsSource": 0, "ExtraRowsTarget": 0}`, + `target:{fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}}|0|{}`, ), nil) vdenv.dbClient.ExpectRequest("update _vt.vdiff_table set state = 'started' where vdiff_id = 1 and table_name = 't1'", singleRowAffected, nil) vdenv.dbClient.ExpectRequest(`insert into _vt.vdiff_log(vdiff_id, message) values (1, 'started: table \'t1\'')`, singleRowAffected, nil) @@ -185,7 +185,7 @@ func TestVDiff(t *testing.T) { "lastpk|mismatch|report", "varbinary|int64|json", ), - `fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}|0|{}`, + `target:{fields:{name:"c1" type:INT64 table:"t1" org_table:"t1" database:"vt_customer" org_name:"c1" column_length:20 charset:63 flags:53251} rows:{lengths:1 values:"1"}}|0|{}`, ), nil) vdenv.dbClient.ExpectRequest(`update _vt.vdiff_table set rows_compared = 0, report = '{"TableName":"t1","ProcessedRows":0,"MatchingRows":0,"MismatchedRows":0,"ExtraRowsSource":0,"ExtraRowsTarget":0}' where vdiff_id = 1 and table_name = 't1'`, singleRowAffected, nil) vdenv.dbClient.ExpectRequest(`update _vt.vdiff_table set state = 'completed', rows_compared = 0, report = '{"TableName":"t1","ProcessedRows":0,"MatchingRows":0,"MismatchedRows":0,"ExtraRowsSource":0,"ExtraRowsTarget":0}' where vdiff_id = 1 and table_name = 't1'`, singleRowAffected, nil) diff --git a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go index 7d4cdb78c20..563741fcd23 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go @@ -678,5 +678,15 @@ func (tvde *testVDiffEnv) createController(t *testing.T, id int) *controller { tvde.dbClient.ExpectRequest(fmt.Sprintf("select * from _vt.vdiff where id = %d", id), noResults, nil) ct, err := newController(context.Background(), controllerQR.Named().Row(), tvde.dbClientFactory, tstenv.TopoServ, tvde.vde, tvde.opts) require.NoError(t, err) + ct.sources = map[string]*migrationSource{ + tstenv.ShardName: { + vrID: 1, + shardStreamer: &shardStreamer{ + tablet: tvde.vde.thisTablet, + shard: tstenv.ShardName, + }, + }, + } + ct.sourceKeyspace = tstenv.KeyspaceName return ct } diff --git a/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go b/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go index 6d016709cce..03be2271d34 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go +++ b/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go @@ -37,9 +37,11 @@ type shardStreamer struct { err error } +var _ engine.StreamExecutor = (*shardStreamer)(nil) + // StreamExecute implements the StreamExecutor interface of the Primitive executor and // it simply waits for a result to be available for this shard and sends it to the merge sorter. -func (sm *shardStreamer) StreamExecute(ctx context.Context, vcursor engine.VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (sm *shardStreamer) StreamExecute(_ context.Context, _ engine.VCursor, _ map[string]*querypb.BindVariable, _, _ bool, callback func(*sqltypes.Result) error) error { for result := range sm.result { if err := callback(result); err != nil { return err diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go index 102d7535af9..1ebeab8ed8d 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go +++ b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go @@ -20,10 +20,12 @@ import ( "context" "encoding/json" "fmt" + "slices" "strings" "sync" "time" + "golang.org/x/exp/maps" "google.golang.org/protobuf/encoding/prototext" "vitess.io/vitess/go/mysql/collations" @@ -34,6 +36,7 @@ import ( "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" @@ -86,9 +89,10 @@ type tableDiffer struct { targetPrimitive engine.Primitive // sourceQuery is computed from the associated query for this table in the vreplication workflow's Rule Filter - sourceQuery string - table *tabletmanagerdatapb.TableDefinition - lastPK *querypb.QueryResult + sourceQuery string + table *tabletmanagerdatapb.TableDefinition + lastSourcePK *querypb.QueryResult + lastTargetPK *querypb.QueryResult // wgShardStreamers is used, with a cancellable context, to wait for all shard streamers // to finish after each diff is complete. @@ -238,15 +242,9 @@ func (td *tableDiffer) selectTablets(ctx context.Context) error { sourceCells := strings.Split(td.wd.opts.PickerOptions.SourceCell, ",") targetCells := strings.Split(td.wd.opts.PickerOptions.TargetCell, ",") - // For Mount+Migrate, the source tablets will be in a different - // Vitess cluster with its own TopoServer. - sourceTopoServer := td.wd.ct.ts - if td.wd.ct.externalCluster != "" { - extTS, err := td.wd.ct.ts.OpenExternalVitessClusterServer(ctx, td.wd.ct.externalCluster) - if err != nil { - return err - } - sourceTopoServer = extTS + sourceTopoServer, err := td.wd.getSourceTopoServer() + if err != nil { + return vterrors.Wrap(err, "failed to get source topo server") } tabletPickerOptions := discovery.TabletPickerOptions{} wg.Add(1) @@ -349,7 +347,7 @@ func (td *tableDiffer) startTargetDataStream(ctx context.Context) error { ct := td.wd.ct gtidch := make(chan string, 1) ct.targetShardStreamer.result = make(chan *sqltypes.Result, 1) - go td.streamOneShard(ctx, ct.targetShardStreamer, td.tablePlan.targetQuery, td.lastPK, gtidch) + go td.streamOneShard(ctx, ct.targetShardStreamer, td.tablePlan.targetQuery, td.lastTargetPK, gtidch) gtid, ok := <-gtidch if !ok { log.Infof("streaming error: %v", ct.targetShardStreamer.err) @@ -364,7 +362,7 @@ func (td *tableDiffer) startSourceDataStreams(ctx context.Context) error { if err := td.forEachSource(func(source *migrationSource) error { gtidch := make(chan string, 1) source.result = make(chan *sqltypes.Result, 1) - go td.streamOneShard(ctx, source.shardStreamer, td.tablePlan.sourceQuery, td.lastPK, gtidch) + go td.streamOneShard(ctx, source.shardStreamer, td.tablePlan.sourceQuery, td.lastSourcePK, gtidch) gtid, ok := <-gtidch if !ok { @@ -721,32 +719,17 @@ func (td *tableDiffer) updateTableProgress(dbClient binlogplayer.DBClient, dr *D if dr == nil { return fmt.Errorf("cannot update progress with a nil diff report") } - var lastPK []byte + var err error var query string rpt, err := json.Marshal(dr) if err != nil { return err } - if lastRow != nil { - lastPK, err = td.lastPKFromRow(lastRow) - if err != nil { - return err - } - - if td.wd.opts.CoreOptions.MaxDiffSeconds > 0 { - // Update the in-memory lastPK as well so that we can restart the table - // diff if needed. - lastpkpb := &querypb.QueryResult{} - if err := prototext.Unmarshal(lastPK, lastpkpb); err != nil { - return err - } - td.lastPK = lastpkpb - } - query, err = sqlparser.ParseAndBind(sqlUpdateTableProgress, + if lastRow == nil { + query, err = sqlparser.ParseAndBind(sqlUpdateTableNoProgress, sqltypes.Int64BindVariable(dr.ProcessedRows), - sqltypes.StringBindVariable(string(lastPK)), sqltypes.StringBindVariable(string(rpt)), sqltypes.Int64BindVariable(td.wd.ct.id), sqltypes.StringBindVariable(td.table.Name), @@ -755,8 +738,25 @@ func (td *tableDiffer) updateTableProgress(dbClient binlogplayer.DBClient, dr *D return err } } else { - query, err = sqlparser.ParseAndBind(sqlUpdateTableNoProgress, + lastPK := td.lastPKFromRow(lastRow) + if td.wd.opts.CoreOptions.MaxDiffSeconds > 0 { + // Update the in-memory lastPK as well so that we can restart the table + // diff if needed. + td.lastTargetPK = lastPK.Target + if lastPK.Source == nil { + // If the source PK is nil, we use the target value for both. + td.lastSourcePK = lastPK.Target + } else { + td.lastSourcePK = lastPK.Source + } + } + lastPKTxt, err := prototext.Marshal(lastPK) + if err != nil { + return vterrors.Wrapf(err, "failed to marshal lastpk value %+v for table %s", lastPK, td.table.Name) + } + query, err = sqlparser.ParseAndBind(sqlUpdateTableProgress, sqltypes.Int64BindVariable(dr.ProcessedRows), + sqltypes.StringBindVariable(string(lastPKTxt)), sqltypes.StringBindVariable(string(rpt)), sqltypes.Int64BindVariable(td.wd.ct.id), sqltypes.StringBindVariable(td.table.Name), @@ -768,6 +768,7 @@ func (td *tableDiffer) updateTableProgress(dbClient binlogplayer.DBClient, dr *D if _, err := dbClient.ExecuteFetch(query, 1); err != nil { return err } + td.wd.ct.TableDiffRowCounts.Add(td.table.Name, dr.ProcessedRows) return nil } @@ -832,19 +833,30 @@ func updateTableMismatch(dbClient binlogplayer.DBClient, vdiffID int64, table st return nil } -func (td *tableDiffer) lastPKFromRow(row []sqltypes.Value) ([]byte, error) { - pkColCnt := len(td.tablePlan.pkCols) - pkFields := make([]*querypb.Field, pkColCnt) - pkVals := make([]sqltypes.Value, pkColCnt) - for i, colIndex := range td.tablePlan.pkCols { - pkFields[i] = td.tablePlan.table.Fields[colIndex] - pkVals[i] = row[colIndex] - } - buf, err := prototext.Marshal(&querypb.QueryResult{ - Fields: pkFields, - Rows: []*querypb.Row{sqltypes.RowToProto3(pkVals)}, - }) - return buf, err +func (td *tableDiffer) lastPKFromRow(row []sqltypes.Value) *tabletmanagerdatapb.VDiffTableLastPK { + buildQR := func(pkCols []int) *querypb.QueryResult { + pkColCnt := len(pkCols) + pkFields := make([]*querypb.Field, pkColCnt) + pkVals := make([]sqltypes.Value, pkColCnt) + for i, colIndex := range pkCols { + pkFields[i] = td.tablePlan.table.Fields[colIndex] + pkVals[i] = row[colIndex] + } + return &querypb.QueryResult{ + Fields: pkFields, + Rows: []*querypb.Row{sqltypes.RowToProto3(pkVals)}, + } + } + lastPK := &tabletmanagerdatapb.VDiffTableLastPK{ + Target: buildQR(td.tablePlan.pkCols), + } + // If the source and target PKs are different, we need to save the source PK + // as well. Otherwise the source will be nil which means that the target value + // should also be used for the source. + if !slices.Equal(td.tablePlan.pkCols, td.tablePlan.sourcePkCols) { + lastPK.Source = buildQR(td.tablePlan.sourcePkCols) + } + return lastPK } // If SourceTimeZone is defined in the BinlogSource (_vt.vreplication.source), the @@ -893,6 +905,83 @@ func (td *tableDiffer) adjustForSourceTimeZone(targetSelectExprs sqlparser.Selec return targetSelectExprs } +// getSourcePKCols populates the sourcePkCols field in the tablePlan. +// We need this information in order to save the lastpk value for the +// source if the PK columns differ between the source and target. +func (td *tableDiffer) getSourcePKCols() error { + ctx, cancel := context.WithTimeout(td.wd.ct.vde.ctx, topo.RemoteOperationTimeout*3) + defer cancel() + + // We use the first sourceShard as all of them should have the same schema. + if len(td.wd.ct.sources) == 0 { + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "no source shards found in %s keyspace", + td.wd.ct.sourceKeyspace) + } + sourceShardName := maps.Keys(td.wd.ct.sources)[0] + sourceTS, err := td.wd.getSourceTopoServer() + if err != nil { + return vterrors.Wrap(err, "failed to get source topo server") + } + sourceShard, err := sourceTS.GetShard(ctx, td.wd.ct.sourceKeyspace, sourceShardName) + if err != nil { + return vterrors.Wrapf(err, "failed to get source shard %s", sourceShardName) + } + if sourceShard.PrimaryAlias == nil { + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "source shard %s has no primary", sourceShardName) + } + sourceTablet, err := sourceTS.GetTablet(ctx, sourceShard.PrimaryAlias) + if err != nil { + return vterrors.Wrapf(err, "failed to get primary tablet in source shard %s/%s", + td.wd.ct.sourceKeyspace, sourceShardName) + } + sourceSchema, err := td.wd.ct.tmc.GetSchema(ctx, sourceTablet.Tablet, &tabletmanagerdatapb.GetSchemaRequest{ + Tables: []string{td.table.Name}, + }) + if err != nil { + return vterrors.Wrapf(err, "failed to get the schema for table %s from source tablet %s", + td.table.Name, topoproto.TabletAliasString(sourceTablet.Tablet.Alias)) + } + sourceTable := sourceSchema.TableDefinitions[0] + if len(sourceTable.PrimaryKeyColumns) == 0 { + // We use the columns from a PKE if there is one. + executeFetch := func(query string, maxrows int, wantfields bool) (*sqltypes.Result, error) { + res, err := td.wd.ct.tmc.ExecuteFetchAsApp(ctx, sourceTablet.Tablet, false, &tabletmanagerdatapb.ExecuteFetchAsAppRequest{ + Query: []byte(query), + MaxRows: 1, + }) + if err != nil { + return nil, vterrors.Wrapf(err, "failed to query the %s source tablet in order to get a primary key equivalent for the %s table", + topoproto.TabletAliasString(sourceTablet.Tablet.Alias), td.table.Name) + } + return sqltypes.Proto3ToResult(res), nil + } + pkeCols, _, err := mysqlctl.GetPrimaryKeyEquivalentColumns(ctx, executeFetch, sourceTablet.DbName(), td.table.Name) + if err != nil { + return vterrors.Wrapf(err, "failed to get a primary key equivalent for the %s table from source tablet %s", + td.table.Name, topoproto.TabletAliasString(sourceTablet.Tablet.Alias)) + } + if len(pkeCols) > 0 { + sourceTable.PrimaryKeyColumns = pkeCols + } else { + // We use every column together as a substitute PK. + sourceTable.PrimaryKeyColumns = append(sourceTable.PrimaryKeyColumns, td.table.Columns...) + } + } + + sourcePKColumns := make(map[string]struct{}, len(sourceTable.PrimaryKeyColumns)) + td.tablePlan.sourcePkCols = make([]int, 0, len(sourceTable.PrimaryKeyColumns)) + for _, pkc := range sourceTable.PrimaryKeyColumns { + sourcePKColumns[pkc] = struct{}{} + } + for i, pkc := range td.table.Columns { + if _, ok := sourcePKColumns[pkc]; ok { + td.tablePlan.sourcePkCols = append(td.tablePlan.sourcePkCols, i) + } + } + + return nil +} + func getColumnNameForSelectExpr(selectExpression sqlparser.SelectExpr) (string, error) { aliasedExpr := selectExpression.(*sqlparser.AliasedExpr) expr := aliasedExpr.Expr diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_differ_test.go b/go/vt/vttablet/tabletmanager/vdiff/table_differ_test.go new file mode 100644 index 00000000000..03ba218cd66 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vdiff/table_differ_test.go @@ -0,0 +1,131 @@ +/* +Copyright 2025 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 vdiff + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/stats" + "vitess.io/vitess/go/vt/binlog/binlogplayer" + + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" +) + +func TestUpdateTableProgress(t *testing.T) { + wd := &workflowDiffer{ + ct: &controller{ + id: 1, + TableDiffRowCounts: stats.NewCountersWithSingleLabel("", "", "Rows"), + }, + opts: &tabletmanagerdatapb.VDiffOptions{ + CoreOptions: &tabletmanagerdatapb.VDiffCoreOptions{ + MaxDiffSeconds: 100, + }, + }, + } + table := &tabletmanagerdatapb.TableDefinition{ + Name: "test", + } + dr := &DiffReport{ + TableName: table.Name, + ProcessedRows: 1e9, + } + queryTemplate := `update _vt.vdiff_table set rows_compared = 1000000000, lastpk = '%s', report = '{"TableName":"test","ProcessedRows":1000000000,"MatchingRows":0,"MismatchedRows":0,"ExtraRowsSource":0,"ExtraRowsTarget":0}' where vdiff_id = 1 and table_name = 'test'` + + testCases := []struct { + name string + fields []*querypb.Field + pkCols []int + sourcePkCols []int + lastRow []sqltypes.Value + expectedLastPK string + wantErr bool + }{ + { + name: "identical PKs", + fields: []*querypb.Field{ + { + Name: "a", Type: sqltypes.Int64, + }, + { + Name: "b", Type: sqltypes.Int64, + }, + }, + pkCols: []int{0, 1}, + sourcePkCols: []int{0, 1}, + lastRow: []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, + expectedLastPK: `target:{fields:{name:"a" type:INT64} fields:{name:"b" type:INT64} rows:{lengths:1 lengths:1 values:"12"}}`, + }, + { + name: "more PK cols on target", + fields: []*querypb.Field{ + { + Name: "a", Type: sqltypes.Int64, + }, + { + Name: "b", Type: sqltypes.Int64, + }, + }, + pkCols: []int{0, 1}, + sourcePkCols: []int{0}, + lastRow: []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, + expectedLastPK: `target:{fields:{name:"a" type:INT64} fields:{name:"b" type:INT64} rows:{lengths:1 lengths:1 values:"12"}} source:{fields:{name:"a" type:INT64} rows:{lengths:1 values:"1"}}`, + }, + { + name: "more PK cols on source", + fields: []*querypb.Field{ + { + Name: "a", Type: sqltypes.Int64, + }, + { + Name: "b", Type: sqltypes.Int64, + }, + }, + pkCols: []int{0}, + sourcePkCols: []int{0, 1}, + lastRow: []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, + expectedLastPK: `target:{fields:{name:"a" type:INT64} rows:{lengths:1 values:"1"}} source:{fields:{name:"a" type:INT64} fields:{name:"b" type:INT64} rows:{lengths:1 lengths:1 values:"12"}}`, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + dbc := binlogplayer.NewMockDBClient(t) + dbc.ExpectRequest(fmt.Sprintf(queryTemplate, tc.expectedLastPK), &sqltypes.Result{}, nil) + td := &tableDiffer{ + wd: wd, + table: table, + tablePlan: &tablePlan{ + pkCols: tc.pkCols, + sourcePkCols: tc.sourcePkCols, + table: &tabletmanagerdatapb.TableDefinition{ + Fields: tc.fields, + }, + }, + } + if err := td.updateTableProgress(dbc, dr, tc.lastRow); (err != nil) != tc.wantErr { + require.FailNow(t, "tableDiffer.updateTableProgress() error = %v, wantErr %v", + err, tc.wantErr) + } + }) + } +} diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_plan.go b/go/vt/vttablet/tabletmanager/vdiff/table_plan.go index 836df8ffe94..b5ea384d864 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/table_plan.go +++ b/go/vt/vttablet/tabletmanager/vdiff/table_plan.go @@ -53,6 +53,11 @@ type tablePlan struct { comparePKs []compareColInfo // pkCols has the indices of PK cols in the select list pkCols []int + // sourcePkCols has the indices of PK cols in the select + // list, but from the source keyspace. This is needed to + // properly store the lastpk for the source when the source + // and target have different PK columns. + sourcePkCols []int // selectPks is the list of pk columns as they appear in the select clause for the diff. selectPks []int diff --git a/go/vt/vttablet/tabletmanager/vdiff/utils.go b/go/vt/vttablet/tabletmanager/vdiff/utils.go index aeaa28972e0..68e8a6acb57 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/utils.go +++ b/go/vt/vttablet/tabletmanager/vdiff/utils.go @@ -80,17 +80,6 @@ func insertVDiffLog(ctx context.Context, dbClient binlogplayer.DBClient, vdiffID } } -func stringListContains(lst []string, item string) bool { - contains := false - for _, t := range lst { - if t == item { - contains = true - break - } - } - return contains -} - // copyNonKeyRangeExpressions copies all expressions from the input WHERE clause // to the output WHERE clause except for any in_keyrange() expressions. func copyNonKeyRangeExpressions(where *sqlparser.Where) *sqlparser.Where { diff --git a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go index ef30d8f14b0..775ae1d9179 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go +++ b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "reflect" + "slices" "strings" "time" @@ -33,6 +34,7 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vtctl/schematools" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -40,7 +42,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) @@ -344,7 +345,7 @@ func (wd *workflowDiffer) buildPlan(dbClient binlogplayer.DBClient, filter *binl for _, table := range schm.TableDefinitions { // if user specified tables explicitly only use those, otherwise diff all tables in workflow - if len(specifiedTables) != 0 && !stringListContains(specifiedTables, table.Name) { + if len(specifiedTables) != 0 && !slices.Contains(specifiedTables, table.Name) { continue } if schema.IsInternalOperationTableName(table.Name) && !schema.IsOnlineDDLTableName(table.Name) { @@ -370,15 +371,24 @@ func (wd *workflowDiffer) buildPlan(dbClient binlogplayer.DBClient, filter *binl } td := newTableDiffer(wd, table, sourceQuery) - lastpkpb, err := wd.getTableLastPK(dbClient, table.Name) + lastPK, err := wd.getTableLastPK(dbClient, table.Name) if err != nil { return err } - td.lastPK = lastpkpb + if lastPK != nil { + td.lastSourcePK = lastPK.Source + td.lastTargetPK = lastPK.Target + } wd.tableDiffers[table.Name] = td if _, err := td.buildTablePlan(dbClient, wd.ct.vde.dbName, wd.collationEnv); err != nil { return err } + // We get the PK columns from the source schema as well as they can differ + // and they determine the proper position to use when saving our progress. + if err := td.getSourcePKCols(); err != nil { + return vterrors.Wrapf(err, "could not get the primary key columns from the %s source keyspace", + wd.ct.sourceKeyspace) + } } if len(wd.tableDiffers) == 0 { return fmt.Errorf("no tables found to diff, %s:%s, on tablet %v", @@ -388,7 +398,7 @@ func (wd *workflowDiffer) buildPlan(dbClient binlogplayer.DBClient, filter *binl } // getTableLastPK gets the lastPK protobuf message for a given vdiff table. -func (wd *workflowDiffer) getTableLastPK(dbClient binlogplayer.DBClient, tableName string) (*querypb.QueryResult, error) { +func (wd *workflowDiffer) getTableLastPK(dbClient binlogplayer.DBClient, tableName string) (*tabletmanagerdatapb.VDiffTableLastPK, error) { query, err := sqlparser.ParseAndBind(sqlGetVDiffTable, sqltypes.Int64BindVariable(wd.ct.id), sqltypes.StringBindVariable(tableName), @@ -406,11 +416,15 @@ func (wd *workflowDiffer) getTableLastPK(dbClient binlogplayer.DBClient, tableNa return nil, err } if len(lastpk) != 0 { - var lastpkpb querypb.QueryResult - if err := prototext.Unmarshal(lastpk, &lastpkpb); err != nil { - return nil, err + lastPK := &tabletmanagerdatapb.VDiffTableLastPK{} + if err := prototext.Unmarshal(lastpk, lastPK); err != nil { + return nil, vterrors.Wrapf(err, "failed to unmarshal lastpk value of %s for the %s table", + string(lastpk), tableName) + } + if lastPK.Source == nil { // Then it's the same as the target + lastPK.Source = lastPK.Target } - return &lastpkpb, nil + return lastPK, nil } } return nil, nil @@ -488,3 +502,14 @@ func (wd *workflowDiffer) initVDiffTables(dbClient binlogplayer.DBClient) error } return nil } + +// getSourceTopoServer returns the source topo server as for Mount+Migrate the +// source tablets will be in a different Vitess cluster with its own TopoServer. +func (wd *workflowDiffer) getSourceTopoServer() (*topo.Server, error) { + if wd.ct.externalCluster == "" { + return wd.ct.ts, nil + } + ctx, cancel := context.WithTimeout(wd.ct.vde.ctx, topo.RemoteOperationTimeout) + defer cancel() + return wd.ct.ts.OpenExternalVitessClusterServer(ctx, wd.ct.externalCluster) +} diff --git a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go index c51b6fdf281..5ac0fabd726 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go @@ -51,6 +51,16 @@ func TestBuildPlanSuccess(t *testing.T) { vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) ct, err := newController(context.Background(), controllerQR.Named().Row(), vdiffenv.dbClientFactory, tstenv.TopoServ, vdiffenv.vde, vdiffenv.opts) require.NoError(t, err) + ct.sources = map[string]*migrationSource{ + tstenv.ShardName: { + vrID: 1, + shardStreamer: &shardStreamer{ + tablet: vdenv.vde.thisTablet, + shard: tstenv.ShardName, + }, + }, + } + ct.sourceKeyspace = tstenv.KeyspaceName testcases := []struct { input *binlogdatapb.Rule @@ -63,14 +73,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 order by c1 asc", - targetQuery: "select c1, c2 from t1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 order by c1 asc", + targetQuery: "select c1, c2 from t1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -83,14 +94,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') order by c1 asc", - targetQuery: "select c1, c2 from t1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') order by c1 asc", + targetQuery: "select c1, c2 from t1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -103,14 +115,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 order by c1 asc", - targetQuery: "select c1, c2 from t1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 order by c1 asc", + targetQuery: "select c1, c2 from t1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -123,14 +136,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c2, c1 from t1 order by c1 asc", - targetQuery: "select c2, c1 from t1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{1}, - selectPks: []int{1}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c2, c1 from t1 order by c1 asc", + targetQuery: "select c2, c1 from t1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{1}, + sourcePkCols: []int{0}, + selectPks: []int{1}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -143,14 +157,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c0 as c1, c2 from t2 order by c1 asc", - targetQuery: "select c1, c2 from t1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c0 as c1, c2 from t2 order by c1 asc", + targetQuery: "select c1, c2 from t1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -164,14 +179,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "nonpktext", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["nonpktext"]], - sourceQuery: "select c1, textcol from nonpktext order by c1 asc", - targetQuery: "select c1, textcol from nonpktext order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "textcol"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["nonpktext"]], + sourceQuery: "select c1, textcol from nonpktext order by c1 asc", + targetQuery: "select c1, textcol from nonpktext order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "textcol"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -185,14 +201,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "nonpktext", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["nonpktext"]], - sourceQuery: "select textcol, c1 from nonpktext order by c1 asc", - targetQuery: "select textcol, c1 from nonpktext order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "textcol"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{1}, - selectPks: []int{1}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["nonpktext"]], + sourceQuery: "select textcol, c1 from nonpktext order by c1 asc", + targetQuery: "select textcol, c1 from nonpktext order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "textcol"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{1}, + sourcePkCols: []int{0}, + selectPks: []int{1}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -206,14 +223,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "pktext", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["pktext"]], - sourceQuery: "select textcol, c2 from pktext order by textcol asc", - targetQuery: "select textcol, c2 from pktext order by textcol asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["pktext"]], + sourceQuery: "select textcol, c2 from pktext order by textcol asc", + targetQuery: "select textcol, c2 from pktext order by textcol asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, + pkCols: []int{0}, + sourcePkCols: []int{}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("textcol")}, Direction: sqlparser.AscOrder, @@ -227,14 +245,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "pktext", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["pktext"]], - sourceQuery: "select c2, textcol from pktext order by textcol asc", - targetQuery: "select c2, textcol from pktext order by textcol asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, - comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, - pkCols: []int{1}, - selectPks: []int{1}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["pktext"]], + sourceQuery: "select c2, textcol from pktext order by textcol asc", + targetQuery: "select c2, textcol from pktext order by textcol asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, + comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, + pkCols: []int{1}, + sourcePkCols: []int{}, + selectPks: []int{1}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("textcol")}, Direction: sqlparser.AscOrder, @@ -248,14 +267,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "nopk", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["nopk"]], - sourceQuery: "select c1, c2, c3 from nopk order by c1 asc, c2 asc, c3 asc", - targetQuery: "select c1, c2, c3 from nopk order by c1 asc, c2 asc, c3 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, - pkCols: []int{0, 1, 2}, - selectPks: []int{0, 1, 2}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["nopk"]], + sourceQuery: "select c1, c2, c3 from nopk order by c1 asc, c2 asc, c3 asc", + targetQuery: "select c1, c2, c3 from nopk order by c1 asc, c2 asc, c3 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, + pkCols: []int{0, 1, 2}, + sourcePkCols: []int{0}, + selectPks: []int{0, 1, 2}, orderBy: sqlparser.OrderBy{ &sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, @@ -279,14 +299,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "nopkwithpke", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["nopkwithpke"]], - sourceQuery: "select c1, c2, c3 from nopkwithpke order by c3 asc", - targetQuery: "select c1, c2, c3 from nopkwithpke order by c3 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, - comparePKs: []compareColInfo{{2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, - pkCols: []int{2}, - selectPks: []int{2}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["nopkwithpke"]], + sourceQuery: "select c1, c2, c3 from nopkwithpke order by c3 asc", + targetQuery: "select c1, c2, c3 from nopkwithpke order by c3 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, + comparePKs: []compareColInfo{{2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c3"}}, + pkCols: []int{2}, + sourcePkCols: []int{0}, + selectPks: []int{2}, orderBy: sqlparser.OrderBy{ &sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c3")}, @@ -302,14 +323,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "pktext", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["pktext"]], - sourceQuery: "select c2, a + b as textcol from pktext order by textcol asc", - targetQuery: "select c2, textcol from pktext order by textcol asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, - comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, - pkCols: []int{1}, - selectPks: []int{1}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["pktext"]], + sourceQuery: "select c2, a + b as textcol from pktext order by textcol asc", + targetQuery: "select c2, textcol from pktext order by textcol asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, + comparePKs: []compareColInfo{{1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "textcol"}}, + pkCols: []int{1}, + sourcePkCols: []int{}, + selectPks: []int{1}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("textcol")}, Direction: sqlparser.AscOrder, @@ -322,14 +344,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "multipk", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["multipk"]], - sourceQuery: "select c1, c2 from multipk order by c1 asc, c2 asc", - targetQuery: "select c1, c2 from multipk order by c1 asc, c2 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}}, - pkCols: []int{0, 1}, - selectPks: []int{0, 1}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["multipk"]], + sourceQuery: "select c1, c2 from multipk order by c1 asc, c2 asc", + targetQuery: "select c1, c2 from multipk order by c1 asc, c2 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c2"}}, + pkCols: []int{0, 1}, + sourcePkCols: []int{0}, + selectPks: []int{0, 1}, orderBy: sqlparser.OrderBy{ &sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, @@ -349,14 +372,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') order by c1 asc", - targetQuery: "select c1, c2 from t1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') order by c1 asc", + targetQuery: "select c1, c2 from t1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -370,14 +394,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc", - targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc", + targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -391,14 +416,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') and c2 = 2 order by c1 asc", - targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') and c2 = 2 order by c1 asc", + targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -412,14 +438,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80') order by c1 asc", - targetQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80') order by c1 asc", + targetQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -433,14 +460,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc", - targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc", + targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -454,14 +482,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "t1", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["t1"]], - sourceQuery: "select c1, c2 from t1 group by c1 order by c1 asc", - targetQuery: "select c1, c2 from t1 order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["t1"]], + sourceQuery: "select c1, c2 from t1 group by c1 order by c1 asc", + targetQuery: "select c1, c2 from t1 order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -475,14 +504,15 @@ func TestBuildPlanSuccess(t *testing.T) { }, table: "aggr", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["aggr"]], - sourceQuery: "select c1, c2, count(*) as c3, sum(c4) as c4 from t1 group by c1 order by c1 asc", - targetQuery: "select c1, c2, c3, c4 from aggr order by c1 asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c3"}, {3, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c4"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["aggr"]], + sourceQuery: "select c1, c2, count(*) as c3, sum(c4) as c4 from t1 group by c1 order by c1 asc", + targetQuery: "select c1, c2, c3, c4 from aggr order by c1 asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}, {2, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c3"}, {3, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c4"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}}, + pkCols: []int{0}, + sourcePkCols: []int{0}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("c1")}, Direction: sqlparser.AscOrder, @@ -500,14 +530,15 @@ func TestBuildPlanSuccess(t *testing.T) { sourceTimeZone: "US/Pacific", table: "datze", tablePlan: &tablePlan{ - dbName: vdiffDBName, - table: testSchema.TableDefinitions[tableDefMap["datze"]], - sourceQuery: "select id, dt from datze order by id asc", - targetQuery: "select id, convert_tz(dt, 'UTC', 'US/Pacific') as dt from datze order by id asc", - compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "id"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "dt"}}, - comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "id"}}, - pkCols: []int{0}, - selectPks: []int{0}, + dbName: vdiffDBName, + table: testSchema.TableDefinitions[tableDefMap["datze"]], + sourceQuery: "select id, dt from datze order by id asc", + targetQuery: "select id, convert_tz(dt, 'UTC', 'US/Pacific') as dt from datze order by id asc", + compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "id"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "dt"}}, + comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "id"}}, + pkCols: []int{0}, + sourcePkCols: []int{}, + selectPks: []int{0}, orderBy: sqlparser.OrderBy{&sqlparser.Order{ Expr: &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("id")}, Direction: sqlparser.AscOrder, diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 12a05a69dbc..9f2647a8770 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -166,8 +166,12 @@ func setup(ctx context.Context) (func(), int) { return cleanup, 0 } -// We run Tests twice, first with full binlog_row_image, then with noblob. -var runNoBlobTest = false +var ( + // We run unit tests twice, first with binlog_row_image=FULL, then with NOBLOB. + runNoBlobTest = false + // When using MySQL 8.0 or later, we set binlog_row_value_options=PARTIAL_JSON. + runPartialJSONTest = false +) // We use this tempDir for creating the external cnfs, since we create the test cluster afterwards. const tempDir = "/tmp" @@ -178,10 +182,14 @@ func TestMain(m *testing.M) { exitCode := func() int { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - if err := utils.SetBinlogRowImageMode("full", tempDir); err != nil { + // binlog-row-value-options=PARTIAL_JSON is only supported in MySQL 8.0 and later. + // We still run unit tests with MySQL 5.7, so we cannot add it to the cnf file + // when using 5.7 or mysqld will fail to start. + runPartialJSONTest = utils.CIDBPlatformIsMySQL8orLater() + if err := utils.SetBinlogRowImageOptions("full", runPartialJSONTest, tempDir); err != nil { panic(err) } - defer utils.SetBinlogRowImageMode("", tempDir) + defer utils.SetBinlogRowImageOptions("", false, tempDir) cancel, ret := setup(ctx) if ret > 0 { return ret @@ -193,10 +201,10 @@ func TestMain(m *testing.M) { cancel() runNoBlobTest = true - if err := utils.SetBinlogRowImageMode("noblob", tempDir); err != nil { + if err := utils.SetBinlogRowImageOptions("noblob", runPartialJSONTest, tempDir); err != nil { panic(err) } - defer utils.SetBinlogRowImageMode("", tempDir) + defer utils.SetBinlogRowImageOptions("", false, tempDir) cancel, ret = setup(ctx) if ret > 0 { return ret diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 62d6166b5ca..a201ce25847 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -17,8 +17,10 @@ limitations under the License. package vreplication import ( + "bytes" "encoding/json" "fmt" + "slices" "sort" "strings" @@ -28,6 +30,8 @@ import ( "vitess.io/vitess/go/mysql/collations/colldata" vjson "vitess.io/vitess/go/mysql/json" "vitess.io/vitess/go/mysql/sqlerror" + "vitess.io/vitess/go/ptr" + "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/sqlparser" @@ -363,7 +367,10 @@ func (tp *TablePlan) bindFieldVal(field *querypb.Field, val *sqltypes.Value) (*q func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor func(string) (*sqltypes.Result, error)) (*sqltypes.Result, error) { // MakeRowTrusted is needed here because Proto3ToResult is not convenient. - var before, after bool + var ( + before, after bool + afterVals []sqltypes.Value + ) bindvars := make(map[string]*querypb.BindVariable, len(tp.Fields)) if rowChange.Before != nil { before = true @@ -377,24 +384,48 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun } } if rowChange.After != nil { + jsonIndex := 0 after = true - vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) + afterVals = sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { - var bindVar *querypb.BindVariable - var newVal *sqltypes.Value - var err error + var ( + bindVar *querypb.BindVariable + newVal *sqltypes.Value + err error + ) if field.Type == querypb.Type_JSON { - if vals[i].IsNull() { // An SQL NULL and not an actual JSON value + switch { + case afterVals[i].IsNull(): // An SQL NULL and not an actual JSON value newVal = &sqltypes.NULL - } else { // A JSON value (which may be a JSON null literal value) - newVal, err = vjson.MarshalSQLValue(vals[i].Raw()) + case rowChange.JsonPartialValues != nil && isBitSet(rowChange.JsonPartialValues.Cols, jsonIndex) && + !slices.Equal(afterVals[i].Raw(), sqltypes.NullBytes): + // An SQL expression that can be converted to a JSON value such as JSON_INSERT(). + // This occurs when using partial JSON values as a result of mysqld using + // binlog-row-value-options=PARTIAL_JSON. + if len(afterVals[i].Raw()) == 0 { + // If the JSON column was NOT updated then the JSON column is marked as + // partial and the diff is empty as a way to exclude it from the AFTER image. + // It still has the data bit set, however, even though it's not really + // present. So we have to account for this by unsetting the data bit so + // that the column's current JSON value is not lost. + setBit(rowChange.DataColumns.Cols, i, false) + newVal = ptr.Of(sqltypes.MakeTrusted(querypb.Type_EXPRESSION, nil)) + } else { + escapedName := sqlescape.EscapeID(field.Name) + newVal = ptr.Of(sqltypes.MakeTrusted(querypb.Type_EXPRESSION, []byte( + fmt.Sprintf(afterVals[i].RawStr(), escapedName), + ))) + } + default: // A JSON value (which may be a JSON null literal value) + newVal, err = vjson.MarshalSQLValue(afterVals[i].Raw()) if err != nil { return nil, err } } bindVar, err = tp.bindFieldVal(field, newVal) + jsonIndex++ } else { - bindVar, err = tp.bindFieldVal(field, &vals[i]) + bindVar, err = tp.bindFieldVal(field, &afterVals[i]) } if err != nil { return nil, err @@ -404,7 +435,7 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun } switch { case !before && after: - // only apply inserts for rows whose primary keys are within the range of rows already copied + // Only apply inserts for rows whose primary keys are within the range of rows already copied. if tp.isOutsidePKRange(bindvars, before, after, "insert") { return nil, nil } @@ -444,6 +475,61 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun if tp.isOutsidePKRange(bindvars, before, after, "insert") { return nil, nil } + if tp.isPartial(rowChange) { + // We need to use a combination of the values in the BEFORE and AFTER image to generate the + // new row. + jsonIndex := 0 + for i, field := range tp.Fields { + if field.Type == querypb.Type_JSON && rowChange.JsonPartialValues != nil { + switch { + case !isBitSet(rowChange.JsonPartialValues.Cols, jsonIndex): + // We use the full AFTER value which we already have. + case len(afterVals[i].Raw()) == 0: + // If the JSON column was NOT updated then the JSON column is marked as partial + // and the diff is empty as a way to exclude it from the AFTER image. So we + // want to use the BEFORE image value. + beforeVal, err := vjson.MarshalSQLValue(bindvars["b_"+field.Name].Value) + if err != nil { + return nil, vterrors.Wrapf(err, "failed to convert JSON to SQL field value for %s.%s when building insert query", + tp.TargetName, field.Name) + } + bindvars["a_"+field.Name], err = tp.bindFieldVal(field, beforeVal) + if err != nil { + return nil, vterrors.Wrapf(err, "failed to bind field value for %s.%s when building insert query", + tp.TargetName, field.Name) + } + default: + // For JSON columns when binlog-row-value-options=PARTIAL_JSON is used and the + // column is marked as partial, we need to wrap the JSON diff function(s) + // around the BEFORE value. + diff := afterVals[i].RawStr() + beforeVal := bindvars["b_"+field.Name].Value + buf := bytes.Buffer{} + buf.Grow(len(beforeVal) + len(sqlparser.Utf8mb4Str) + 2) // +2 is for the enclosing quotes + buf.WriteString(sqlparser.Utf8mb4Str) + buf.WriteByte('\'') + buf.Write(beforeVal) + buf.WriteByte('\'') + newVal := sqltypes.MakeTrusted(querypb.Type_EXPRESSION, []byte( + fmt.Sprintf(diff, buf.String()), + )) + bv, err := tp.bindFieldVal(field, &newVal) + if err != nil { + return nil, vterrors.Wrapf(err, "failed to bind field value for %s.%s when building insert query", + tp.TargetName, field.Name) + } + bindvars["a_"+field.Name] = bv + } + jsonIndex++ + continue + } + if !isBitSet(rowChange.DataColumns.Cols, i) { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, + "binary log event missing a needed value for %s.%s due to not using binlog-row-image=FULL; you will need to re-run the workflow with binlog-row-image=FULL", + tp.TargetName, field.Name) + } + } + } return execParsedQuery(tp.Insert, bindvars, executor) } // Unreachable. @@ -540,11 +626,28 @@ func (tp *TablePlan) applyBulkInsertChanges(rowInserts []*binlogdatapb.RowChange newStmt := true for _, rowInsert := range rowInserts { + var ( + err error + bindVar *querypb.BindVariable + ) rowValues := &strings.Builder{} bindvars := make(map[string]*querypb.BindVariable, len(tp.Fields)) vals := sqltypes.MakeRowTrusted(tp.Fields, rowInsert.After) for n, field := range tp.Fields { - bindVar, err := tp.bindFieldVal(field, &vals[n]) + if field.Type == querypb.Type_JSON { + var jsVal *sqltypes.Value + if vals[n].IsNull() { // An SQL NULL and not an actual JSON value + jsVal = &sqltypes.NULL + } else { // A JSON value (which may be a JSON null literal value) + jsVal, err = vjson.MarshalSQLValue(vals[n].Raw()) + if err != nil { + return nil, err + } + } + bindVar, err = tp.bindFieldVal(field, jsVal) + } else { + bindVar, err = tp.bindFieldVal(field, &vals[n]) + } if err != nil { return nil, err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_partial.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_partial.go index 85e0fd8e50f..bc3088bbb44 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_partial.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_partial.go @@ -26,7 +26,6 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - vttablet "vitess.io/vitess/go/vt/vttablet/common" ) // isBitSet returns true if the bit at index is set @@ -36,14 +35,22 @@ func isBitSet(data []byte, index int) bool { return data[byteIndex]&bitMask > 0 } -func (tp *TablePlan) isPartial(rowChange *binlogdatapb.RowChange) bool { - if (tp.WorkflowConfig.ExperimentalFlags /**/ & /**/ vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage) == 0 || - rowChange.DataColumns == nil || - rowChange.DataColumns.Count == 0 { +func setBit(data []byte, index int, value bool) { + byteIndex := index / 8 + bitMask := byte(1 << (uint(index) & 0x7)) + if value { + data[byteIndex] |= bitMask + } else { + data[byteIndex] &= 0xff - bitMask + } +} +func (tp *TablePlan) isPartial(rowChange *binlogdatapb.RowChange) bool { + if rowChange == nil { return false } - return true + return (rowChange.DataColumns != nil && rowChange.DataColumns.Count > 0) || + (rowChange.JsonPartialValues != nil && rowChange.JsonPartialValues.Count > 0) } func (tpb *tablePlanBuilder) generatePartialValuesPart(buf *sqlparser.TrackedBuffer, bvf *bindvarFormatter, dataColumns *binlogdatapb.RowChange_Bitmap) *sqlparser.ParsedQuery { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 98e36119622..31ab895934c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -125,7 +125,8 @@ func newVPlayer(vr *vreplicator, settings binlogplayer.VRSettings, copyState map settings.StopPos = pausePos saveStop = false } - + log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, filter: %+v", + vr.id, settings.StartPos, settings.StopPos, vr.source.Filter) queryFunc := func(ctx context.Context, sql string) (*sqltypes.Result, error) { return vr.dbClient.ExecuteWithRetry(ctx, sql) } @@ -142,7 +143,7 @@ func newVPlayer(vr *vreplicator, settings binlogplayer.VRSettings, copyState map maxAllowedPacket := int64(vr.workflowConfig.RelayLogMaxSize) // We explicitly do NOT want to batch this, we want to send it down the wire // immediately so we use ExecuteFetch directly. - res, err := vr.dbClient.ExecuteFetch("select @@session.max_allowed_packet as max_allowed_packet", 1) + res, err := vr.dbClient.ExecuteFetch(SqlMaxAllowedPacket, 1) if err != nil { log.Errorf("Error getting max_allowed_packet, will use the relay_log_max_size value of %d bytes: %v", vr.workflowConfig.RelayLogMaxSize, err) } else { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index 50d93e60e5a..1267ad5e20c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -1519,6 +1519,296 @@ func TestPlayerRowMove(t *testing.T) { validateQueryCountStat(t, "replicate", 3) } +// TestPlayerPartialImages tests the behavior of the vplayer when modifying +// a table with BLOB and JSON columns, including when modifying the Primary +// Key for a row, when we have partial binlog images, meaning that +// binlog-row-image=NOBLOB and/or binlog-row-value-options=PARTIAL_JSON. +func TestPlayerPartialImages(t *testing.T) { + if !runPartialJSONTest { + t.Skip("Skipping test as binlog_row_value_options=PARTIAL_JSON is not enabled") + } + + defer deleteTablet(addTablet(100)) + execStatements(t, []string{ + "create table src (id int, jd json, bd blob, primary key(id))", + fmt.Sprintf("create table %s.dst (id int, jd json, bd blob, primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table src", + fmt.Sprintf("drop table %s.dst", vrepldb), + }) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "dst", + Filter: "select * from src", + }}, + } + bls := &binlogdatapb.BinlogSource{ + Keyspace: env.KeyspaceName, + Shard: env.ShardName, + Filter: filter, + OnDdl: binlogdatapb.OnDDLAction_IGNORE, + } + cancel, _ := startVReplication(t, bls, "") + defer cancel() + + type testCase struct { + input string + output []string + data [][]string + error string + } + + var testCases []testCase + + if vttablet.DefaultVReplicationConfig.ExperimentalFlags&vttablet.VReplicationExperimentalFlagVPlayerBatching == 0 { + testCases = append(testCases, testCase{ + input: "insert into src (id, jd, bd) values (1,'{\"key1\": \"val1\"}','blob data'), (2,'{\"key2\": \"val2\"}','blob data2'), (3,'{\"key3\": \"val3\"}','blob data3')", + output: []string{ + "insert into dst(id,jd,bd) values (1,JSON_OBJECT(_utf8mb4'key1', _utf8mb4'val1'),_binary'blob data')", + "insert into dst(id,jd,bd) values (2,JSON_OBJECT(_utf8mb4'key2', _utf8mb4'val2'),_binary'blob data2')", + "insert into dst(id,jd,bd) values (3,JSON_OBJECT(_utf8mb4'key3', _utf8mb4'val3'),_binary'blob data3')", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\"}", "blob data"}, + {"2", "{\"key2\": \"val2\"}", "blob data2"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + }, + }) + } else { + testCases = append(testCases, testCase{ + input: "insert into src (id, jd, bd) values (1,'{\"key1\": \"val1\"}','blob data'), (2,'{\"key2\": \"val2\"}','blob data2'), (3,'{\"key3\": \"val3\"}','blob data3')", + output: []string{ + "insert into dst(id,jd,bd) values (1,JSON_OBJECT(_utf8mb4'key1', _utf8mb4'val1'),_binary'blob data'), (2,JSON_OBJECT(_utf8mb4'key2', _utf8mb4'val2'),_binary'blob data2'), (3,JSON_OBJECT(_utf8mb4'key3', _utf8mb4'val3'),_binary'blob data3')", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\"}", "blob data"}, + {"2", "{\"key2\": \"val2\"}", "blob data2"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + }, + }) + } + if runNoBlobTest { + testCases = append(testCases, testCase{ + input: `update src set jd=JSON_SET(jd, '$.color', 'red') where id = 1`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.color', CAST(JSON_QUOTE(_utf8mb4'red') as JSON)) where id=1", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\"}", "blob data"}, + {"2", "{\"key2\": \"val2\"}", "blob data2"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + }, + }) + } else { + testCases = append(testCases, testCase{ + input: `update src set jd=JSON_SET(jd, '$.color', 'red') where id = 1`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.color', CAST(JSON_QUOTE(_utf8mb4'red') as JSON)), bd=_binary'blob data' where id=1", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\"}", "blob data"}, + {"2", "{\"key2\": \"val2\"}", "blob data2"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + }, + }) + } + testCases = append(testCases, []testCase{ + { + input: `update src set bd = 'new blob data' where id = 2`, + output: []string{ + "update dst set bd=_binary'new blob data' where id=2", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\"}", "blob data"}, + {"2", "{\"key2\": \"val2\"}", "new blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + }, + }, + { + input: `update src set id = id+10, bd = 'newest blob data' where id = 2`, + output: []string{ + "delete from dst where id=2", + "insert into dst(id,jd,bd) values (12,JSON_OBJECT(_utf8mb4'key2', _utf8mb4'val2'),_binary'newest blob data')", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\"}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\"}", "newest blob data"}, + }, + }, + }...) + if runNoBlobTest { + testCases = append(testCases, []testCase{ + { + input: `update src set jd=JSON_SET(jd, '$.years', 5) where id = 1`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.years', CAST(5 as JSON)) where id=1", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\"}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.hobbies', JSON_ARRAY('skiing', 'video games', 'hiking')) where id = 1`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.hobbies', JSON_ARRAY(_utf8mb4'skiing', _utf8mb4'video games', _utf8mb4'hiking')) where id=1", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\"}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.misc', '{"address":"1012 S Park", "town":"Hastings", "state":"MI"}') where id = 12`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.misc', CAST(JSON_QUOTE(_utf8mb4'{\"address\":\"1012 S Park\", \"town\":\"Hastings\", \"state\":\"MI\"}') as JSON)) where id=12", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\", \"misc\": \"{\\\"address\\\":\\\"1012 S Park\\\", \\\"town\\\":\\\"Hastings\\\", \\\"state\\\":\\\"MI\\\"}\"}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.current', true) where id = 12`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.current', CAST(_utf8mb4'true' as JSON)) where id=12", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\", \"misc\": \"{\\\"address\\\":\\\"1012 S Park\\\", \\\"town\\\":\\\"Hastings\\\", \\\"state\\\":\\\"MI\\\"}\", \"current\": true}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.idontknow', null, '$.idontknoweither', 'null') where id = 3`, + output: []string{ + "update dst set jd=JSON_INSERT(JSON_INSERT(`jd`, _utf8mb4'$.idontknow', CAST(_utf8mb4'null' as JSON)), _utf8mb4'$.idontknoweither', CAST(JSON_QUOTE(_utf8mb4'null') as JSON)) where id=3", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\", \"idontknow\": null, \"idontknoweither\": \"null\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\", \"misc\": \"{\\\"address\\\":\\\"1012 S Park\\\", \\\"town\\\":\\\"Hastings\\\", \\\"state\\\":\\\"MI\\\"}\", \"current\": true}", "newest blob data"}, + }, + }, + { + input: `update src set id = id+10 where id = 3`, + error: "binary log event missing a needed value for dst.bd due to not using binlog-row-image=FULL", + }, + }...) + } else { + testCases = append(testCases, []testCase{ + { + input: `update src set jd=JSON_SET(jd, '$.years', 5) where id = 1`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.years', CAST(5 as JSON)), bd=_binary'blob data' where id=1", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\"}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.hobbies', JSON_ARRAY('skiing', 'video games', 'hiking')) where id = 1`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.hobbies', JSON_ARRAY(_utf8mb4'skiing', _utf8mb4'video games', _utf8mb4'hiking')), bd=_binary'blob data' where id=1", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\"}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.misc', '{"address":"1012 S Park", "town":"Hastings", "state":"MI"}') where id = 12`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.misc', CAST(JSON_QUOTE(_utf8mb4'{\"address\":\"1012 S Park\", \"town\":\"Hastings\", \"state\":\"MI\"}') as JSON)), bd=_binary'newest blob data' where id=12", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\", \"misc\": \"{\\\"address\\\":\\\"1012 S Park\\\", \\\"town\\\":\\\"Hastings\\\", \\\"state\\\":\\\"MI\\\"}\"}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.current', true) where id = 12`, + output: []string{ + "update dst set jd=JSON_INSERT(`jd`, _utf8mb4'$.current', CAST(_utf8mb4'true' as JSON)), bd=_binary'newest blob data' where id=12", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\", \"misc\": \"{\\\"address\\\":\\\"1012 S Park\\\", \\\"town\\\":\\\"Hastings\\\", \\\"state\\\":\\\"MI\\\"}\", \"current\": true}", "newest blob data"}, + }, + }, + { + input: `update src set jd=JSON_SET(jd, '$.idontknow', null, '$.idontknoweither', 'null') where id = 3`, + output: []string{ + "update dst set jd=JSON_INSERT(JSON_INSERT(`jd`, _utf8mb4'$.idontknow', CAST(_utf8mb4'null' as JSON)), _utf8mb4'$.idontknoweither', CAST(JSON_QUOTE(_utf8mb4'null') as JSON)), bd=_binary'blob data3' where id=3", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"3", "{\"key3\": \"val3\", \"idontknow\": null, \"idontknoweither\": \"null\"}", "blob data3"}, + {"12", "{\"key2\": \"val2\", \"misc\": \"{\\\"address\\\":\\\"1012 S Park\\\", \\\"town\\\":\\\"Hastings\\\", \\\"state\\\":\\\"MI\\\"}\", \"current\": true}", "newest blob data"}, + }, + }, + { + input: `update src set id = id+10 where id = 3`, + output: []string{ + "delete from dst where id=3", + "insert into dst(id,jd,bd) values (13,JSON_OBJECT(_utf8mb4'idontknow', null, _utf8mb4'idontknoweither', _utf8mb4'null', _utf8mb4'key3', _utf8mb4'val3'),_binary'blob data3')", + }, + data: [][]string{ + {"1", "{\"key1\": \"val1\", \"color\": \"red\", \"years\": 5, \"hobbies\": [\"skiing\", \"video games\", \"hiking\"]}", "blob data"}, + {"12", "{\"key2\": \"val2\", \"misc\": \"{\\\"address\\\":\\\"1012 S Park\\\", \\\"town\\\":\\\"Hastings\\\", \\\"state\\\":\\\"MI\\\"}\", \"current\": true}", "newest blob data"}, + {"13", "{\"key3\": \"val3\", \"idontknow\": null, \"idontknoweither\": \"null\"}", "blob data3"}, + }, + }, + }...) + } + + for _, tc := range testCases { + t.Run(tc.input, func(t *testing.T) { + execStatements(t, []string{tc.input}) + var want qh.ExpectationSequencer + if tc.error != "" { + if vttablet.DefaultVReplicationConfig.ExperimentalFlags&vttablet.VReplicationExperimentalFlagVPlayerBatching == 0 { + want = qh.Expect( + "begin", + "delete from dst where id=3", + "rollback", + ).Then(qh.Immediately( + fmt.Sprintf("/update _vt.vreplication set message=.*%s.*", tc.error), + )) + } else { + want = qh.Expect( + "rollback", + ).Then(qh.Immediately( + fmt.Sprintf("/update _vt.vreplication set message=.*%s.*", tc.error), + )) + } + expectDBClientQueries(t, want) + } else { + want = qh.Expect( + "begin", + tc.output..., + ).Then(qh.Immediately( + "/update _vt.vreplication set pos=", + "commit", + )) + expectDBClientQueries(t, want) + expectData(t, "dst", tc.data) + } + }) + } +} + func TestPlayerTypes(t *testing.T) { defer deleteTablet(addTablet(100)) execStatements(t, []string{ @@ -1575,12 +1865,14 @@ func TestPlayerTypes(t *testing.T) { } cancel, _ := startVReplication(t, bls, "") defer cancel() + type testcase struct { input string output string table string data [][]string } + testcases := []testcase{{ input: "insert into vitess_ints values(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648, 4294967295, -9223372036854775808, 18446744073709551615, 2012)", output: "insert into vitess_ints(tiny,tinyu,small,smallu,medium,mediumu,normal,normalu,big,bigu,y) values (-128,255,-32768,65535,-8388608,16777215,-2147483648,4294967295,-9223372036854775808,18446744073709551615,2012)", @@ -1653,15 +1945,30 @@ func TestPlayerTypes(t *testing.T) { {"1", "", "{}", "123", `{"a": [42, 100]}`, `{"foo": "bar"}`}, {"2", "null", `{"name": null}`, "123", `{"a": [42, 100]}`, `{"foo": "bar"}`}, }, - }, { - input: "update vitess_json set val1 = '{\"bar\": \"foo\"}', val4 = '{\"a\": [98, 123]}', val5 = convert(x'7b7d' using utf8mb4) where id=1", - output: "update vitess_json set val1=JSON_OBJECT(_utf8mb4'bar', _utf8mb4'foo'), val2=JSON_OBJECT(), val3=CAST(123 as JSON), val4=JSON_OBJECT(_utf8mb4'a', JSON_ARRAY(98, 123)), val5=JSON_OBJECT() where id=1", - table: "vitess_json", - data: [][]string{ - {"1", `{"bar": "foo"}`, "{}", "123", `{"a": [98, 123]}`, `{}`}, - {"2", "null", `{"name": null}`, "123", `{"a": [42, 100]}`, `{"foo": "bar"}`}, - }, }} + if runPartialJSONTest { + // With partial JSON values we don't replicate the JSON columns that aren't + // actually updated. + testcases = append(testcases, testcase{ + input: "update vitess_json set val1 = '{\"bar\": \"foo\"}', val4 = '{\"a\": [98, 123]}', val5 = convert(x'7b7d' using utf8mb4) where id=1", + output: "update vitess_json set val1=JSON_OBJECT(_utf8mb4'bar', _utf8mb4'foo'), val4=JSON_OBJECT(_utf8mb4'a', JSON_ARRAY(98, 123)), val5=JSON_OBJECT() where id=1", + table: "vitess_json", + data: [][]string{ + {"1", `{"bar": "foo"}`, "{}", "123", `{"a": [98, 123]}`, `{}`}, + {"2", "null", `{"name": null}`, "123", `{"a": [42, 100]}`, `{"foo": "bar"}`}, + }, + }) + } else { + testcases = append(testcases, testcase{ + input: "update vitess_json set val1 = '{\"bar\": \"foo\"}', val4 = '{\"a\": [98, 123]}', val5 = convert(x'7b7d' using utf8mb4) where id=1", + output: "update vitess_json set val1=JSON_OBJECT(_utf8mb4'bar', _utf8mb4'foo'), val2=JSON_OBJECT(), val3=CAST(123 as JSON), val4=JSON_OBJECT(_utf8mb4'a', JSON_ARRAY(98, 123)), val5=JSON_OBJECT() where id=1", + table: "vitess_json", + data: [][]string{ + {"1", `{"bar": "foo"}`, "{}", "123", `{"a": [98, 123]}`, `{}`}, + {"2", "null", `{"name": null}`, "123", `{"a": [42, 100]}`, `{"foo": "bar"}`}, + }, + }) + } for _, tcases := range testcases { execStatements(t, []string{tcases.input}) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index 42701288a44..76177b56b5b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -89,6 +89,7 @@ const ( json_unquote(json_extract(action, '$.type'))=%a and vrepl_id=%a and table_name=%a` sqlDeletePostCopyAction = `delete from _vt.post_copy_action where vrepl_id=%a and table_name=%a and id=%a` + SqlMaxAllowedPacket = "select @@session.max_allowed_packet as max_allowed_packet" ) // vreplicator provides the core logic to start vreplication streams diff --git a/go/vt/vttablet/tabletserver/connpool/pool.go b/go/vt/vttablet/tabletserver/connpool/pool.go index 14fcc6d0f2e..141d8257062 100644 --- a/go/vt/vttablet/tabletserver/connpool/pool.go +++ b/go/vt/vttablet/tabletserver/connpool/pool.go @@ -69,6 +69,7 @@ func NewPool(env tabletenv.Env, name string, cfg tabletenv.ConnPoolConfig) *Pool config := smartconnpool.Config[*Conn]{ Capacity: int64(cfg.Size), IdleTimeout: cfg.IdleTimeout, + MaxIdleCount: int64(cfg.MaxIdleCount), MaxLifetime: cfg.MaxLifetime, RefreshInterval: mysqlctl.PoolDynamicHostnameResolution, } diff --git a/go/vt/vttablet/tabletserver/connpool/pool_test.go b/go/vt/vttablet/tabletserver/connpool/pool_test.go index 8cf27cbb327..c305c61b7b4 100644 --- a/go/vt/vttablet/tabletserver/connpool/pool_test.go +++ b/go/vt/vttablet/tabletserver/connpool/pool_test.go @@ -55,10 +55,10 @@ func TestConnPoolTimeout(t *testing.T) { defer db.Close() cfg := tabletenv.ConnPoolConfig{ - Size: 1, + Size: 1, + Timeout: time.Second, + IdleTimeout: 10 * time.Second, } - cfg.Timeout = time.Second - cfg.IdleTimeout = 10 * time.Second connPool := NewPool(tabletenv.NewEnv(vtenv.NewTestEnv(), nil, "PoolTest"), "TestPool", cfg) params := dbconfigs.New(db.ConnParams()) connPool.Open(params, params, params) @@ -135,6 +135,58 @@ func TestConnPoolSetCapacity(t *testing.T) { } } +// TestConnPoolMaxIdleCount tests the max idle count for the pool. +// The pool should close the idle connections if the idle count is more than the allowed idle count. +// Changing the pool capacity will affect the idle count allowed for that pool. +func TestConnPoolMaxIdleCount(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + cfg := tabletenv.ConnPoolConfig{ + Size: 5, + MaxIdleCount: 2, + } + connPool := NewPool(tabletenv.NewEnv(vtenv.NewTestEnv(), nil, "PoolTest"), "TestPool", cfg) + params := dbconfigs.New(db.ConnParams()) + connPool.Open(params, params, params) + defer connPool.Close() + + assert.EqualValues(t, 5, connPool.Capacity(), "pool capacity should be 5") + assert.EqualValues(t, 2, connPool.IdleCount(), "pool idle count should be 2") + + var conns []*PooledConn + for i := 0; i < 3; i++ { + conn, err := connPool.Get(context.Background(), nil) + require.NoError(t, err) + conns = append(conns, conn) + } + + // after recycle - 1 idle connection + conns[0].Recycle() + assert.Zero(t, connPool.Metrics.IdleClosed(), "pool idle closed should be 0") + + // after recycle - 2 idle connection + conns[1].Recycle() + assert.Zero(t, connPool.Metrics.IdleClosed(), "pool idle closed should be 0") + + // after recycle - 3 idle connection, 1 will be closed + conns[2].Recycle() + assert.EqualValues(t, 1, connPool.Metrics.IdleClosed(), "pool idle closed should be 1") + + // changing the pool capacity will affect the idle count allowed for that pool. + // If setting the capacity to lower value than max idle count. + + err := connPool.SetCapacity(context.Background(), 4) + require.NoError(t, err) + assert.EqualValues(t, 4, connPool.Capacity(), "pool capacity should be 4") + assert.EqualValues(t, 2, connPool.IdleCount(), "pool idle count should be 2") + + err = connPool.SetCapacity(context.Background(), 1) + require.NoError(t, err) + assert.EqualValues(t, 1, connPool.Capacity(), "pool capacity should be 1") + assert.EqualValues(t, 1, connPool.IdleCount(), "pool idle count should be changed to 1") +} + func TestConnPoolStatJSON(t *testing.T) { db := fakesqldb.New(t) defer db.Close() diff --git a/go/vt/vttablet/tabletserver/controller.go b/go/vt/vttablet/tabletserver/controller.go index cef0dd2baee..ab2875ae27b 100644 --- a/go/vt/vttablet/tabletserver/controller.go +++ b/go/vt/vttablet/tabletserver/controller.go @@ -119,6 +119,12 @@ type Controller interface { // WaitForPreparedTwoPCTransactions waits for all prepared transactions to be resolved. WaitForPreparedTwoPCTransactions(ctx context.Context) error + + // SetDemotePrimaryStalled marks that demote primary is stalled in the state manager. + SetDemotePrimaryStalled() + + // IsDiskStalled returns if the disk is stalled. + IsDiskStalled() bool } // Ensure TabletServer satisfies Controller interface. diff --git a/go/vt/vttablet/tabletserver/disk_health_monitor.go b/go/vt/vttablet/tabletserver/disk_health_monitor.go new file mode 100644 index 00000000000..f477f7fd30c --- /dev/null +++ b/go/vt/vttablet/tabletserver/disk_health_monitor.go @@ -0,0 +1,168 @@ +/* +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 tabletserver + +import ( + "context" + "os" + "path" + "strconv" + "sync" + "time" + + "github.com/spf13/pflag" + + "vitess.io/vitess/go/vt/servenv" +) + +var ( + stalledDiskWriteDir = "" + stalledDiskWriteTimeout = 30 * time.Second + stalledDiskWriteInterval = 5 * time.Second +) + +func init() { + servenv.OnParseFor("vtcombo", registerInitFlags) + servenv.OnParseFor("vttablet", registerInitFlags) +} + +func registerInitFlags(fs *pflag.FlagSet) { + fs.StringVar(&stalledDiskWriteDir, "disk-write-dir", stalledDiskWriteDir, "if provided, tablet will attempt to write a file to this directory to check if the disk is stalled") + fs.DurationVar(&stalledDiskWriteTimeout, "disk-write-timeout", stalledDiskWriteTimeout, "if writes exceed this duration, the disk is considered stalled") + fs.DurationVar(&stalledDiskWriteInterval, "disk-write-interval", stalledDiskWriteInterval, "how often to write to the disk to check whether it is stalled") +} + +type DiskHealthMonitor interface { + // IsDiskStalled returns true if the disk is stalled or rejecting writes. + IsDiskStalled() bool +} + +func newDiskHealthMonitor(ctx context.Context) DiskHealthMonitor { + if stalledDiskWriteDir == "" { + return newNoopDiskHealthMonitor() + } + + return newPollingDiskHealthMonitor(ctx, attemptFileWrite, stalledDiskWriteInterval, stalledDiskWriteTimeout) +} + +type writeFunction func() error + +func attemptFileWrite() error { + file, err := os.Create(path.Join(stalledDiskWriteDir, ".stalled_disk_check")) + if err != nil { + return err + } + _, err = file.WriteString(strconv.FormatInt(time.Now().UnixNano(), 10)) + if err != nil { + return err + } + err = file.Sync() + if err != nil { + return err + } + return file.Close() +} + +type pollingDiskHealthMonitor struct { + stalledMutex sync.RWMutex + stalled bool + writeInProgressMutex sync.RWMutex + writeInProgress bool + writeFunc writeFunction + pollingInterval time.Duration + writeTimeout time.Duration +} + +var _ DiskHealthMonitor = &pollingDiskHealthMonitor{} + +func newPollingDiskHealthMonitor(ctx context.Context, writeFunc writeFunction, pollingInterval, writeTimeout time.Duration) *pollingDiskHealthMonitor { + fs := &pollingDiskHealthMonitor{ + stalledMutex: sync.RWMutex{}, + stalled: false, + writeInProgressMutex: sync.RWMutex{}, + writeInProgress: false, + writeFunc: writeFunc, + pollingInterval: pollingInterval, + writeTimeout: writeTimeout, + } + go fs.poll(ctx) + return fs +} + +func (fs *pollingDiskHealthMonitor) poll(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case <-time.After(fs.pollingInterval): + if fs.isWriteInProgress() { + continue + } + + ch := make(chan error, 1) + go func() { + fs.setIsWriteInProgress(true) + err := fs.writeFunc() + fs.setIsWriteInProgress(false) + ch <- err + }() + + select { + case <-time.After(fs.writeTimeout): + fs.setIsDiskStalled(true) + case err := <-ch: + fs.setIsDiskStalled(err != nil) + } + } + } +} + +func (fs *pollingDiskHealthMonitor) IsDiskStalled() bool { + fs.stalledMutex.RLock() + defer fs.stalledMutex.RUnlock() + return fs.stalled +} + +func (fs *pollingDiskHealthMonitor) setIsDiskStalled(isStalled bool) { + fs.stalledMutex.Lock() + defer fs.stalledMutex.Unlock() + fs.stalled = isStalled +} + +func (fs *pollingDiskHealthMonitor) isWriteInProgress() bool { + fs.writeInProgressMutex.RLock() + defer fs.writeInProgressMutex.RUnlock() + return fs.writeInProgress +} + +func (fs *pollingDiskHealthMonitor) setIsWriteInProgress(isInProgress bool) { + fs.writeInProgressMutex.Lock() + defer fs.writeInProgressMutex.Unlock() + fs.writeInProgress = isInProgress +} + +type noopDiskHealthMonitor struct{} + +var _ DiskHealthMonitor = &noopDiskHealthMonitor{} + +func newNoopDiskHealthMonitor() DiskHealthMonitor { + return &noopDiskHealthMonitor{} +} + +func (fs *noopDiskHealthMonitor) IsDiskStalled() bool { + return false +} diff --git a/go/vt/vttablet/tabletserver/disk_health_monitor_test.go b/go/vt/vttablet/tabletserver/disk_health_monitor_test.go new file mode 100644 index 00000000000..8b47e40ee79 --- /dev/null +++ b/go/vt/vttablet/tabletserver/disk_health_monitor_test.go @@ -0,0 +1,119 @@ +/* +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 tabletserver + +import ( + "context" + "errors" + "sync" + "testing" + "time" +) + +func TestDiskHealthMonitor_noStall(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + mockFileWriter := &sequencedMockWriter{} + diskHealthMonitor := newPollingDiskHealthMonitor(ctx, mockFileWriter.mockWriteFunction, 50*time.Millisecond, 25*time.Millisecond) + + time.Sleep(300 * time.Millisecond) + if totalCreateCalls := mockFileWriter.getTotalCreateCalls(); totalCreateCalls != 5 { + t.Fatalf("expected 5 calls to createFile, got %d", totalCreateCalls) + } + if isStalled := diskHealthMonitor.IsDiskStalled(); isStalled { + t.Fatalf("expected isStalled to be false") + } +} + +func TestDiskHealthMonitor_stallAndRecover(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + mockFileWriter := &sequencedMockWriter{sequencedWriteFunctions: []writeFunction{delayedWriteFunction(10*time.Millisecond, nil), delayedWriteFunction(300*time.Millisecond, nil)}} + diskHealthMonitor := newPollingDiskHealthMonitor(ctx, mockFileWriter.mockWriteFunction, 50*time.Millisecond, 25*time.Millisecond) + + time.Sleep(300 * time.Millisecond) + if totalCreateCalls := mockFileWriter.getTotalCreateCalls(); totalCreateCalls != 2 { + t.Fatalf("expected 2 calls to createFile, got %d", totalCreateCalls) + } + if isStalled := diskHealthMonitor.IsDiskStalled(); !isStalled { + t.Fatalf("expected isStalled to be true") + } + + time.Sleep(300 * time.Millisecond) + if totalCreateCalls := mockFileWriter.getTotalCreateCalls(); totalCreateCalls < 5 { + t.Fatalf("expected at least 5 calls to createFile, got %d", totalCreateCalls) + } + if isStalled := diskHealthMonitor.IsDiskStalled(); isStalled { + t.Fatalf("expected isStalled to be false") + } +} + +func TestDiskHealthMonitor_stallDetected(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + mockFileWriter := &sequencedMockWriter{defaultWriteFunction: delayedWriteFunction(10*time.Millisecond, errors.New("test error"))} + diskHealthMonitor := newPollingDiskHealthMonitor(ctx, mockFileWriter.mockWriteFunction, 50*time.Millisecond, 25*time.Millisecond) + + time.Sleep(300 * time.Millisecond) + if totalCreateCalls := mockFileWriter.getTotalCreateCalls(); totalCreateCalls != 5 { + t.Fatalf("expected 5 calls to createFile, got %d", totalCreateCalls) + } + if isStalled := diskHealthMonitor.IsDiskStalled(); !isStalled { + t.Fatalf("expected isStalled to be true") + } +} + +type sequencedMockWriter struct { + defaultWriteFunction writeFunction + sequencedWriteFunctions []writeFunction + + totalCreateCalls int + totalCreateCallsMutex sync.RWMutex +} + +func (smw *sequencedMockWriter) mockWriteFunction() error { + functionIndex := smw.getTotalCreateCalls() + smw.incrementTotalCreateCalls() + + if functionIndex >= len(smw.sequencedWriteFunctions) { + if smw.defaultWriteFunction != nil { + return smw.defaultWriteFunction() + } + return delayedWriteFunction(10*time.Millisecond, nil)() + } + + return smw.sequencedWriteFunctions[functionIndex]() +} + +func (smw *sequencedMockWriter) incrementTotalCreateCalls() { + smw.totalCreateCallsMutex.Lock() + defer smw.totalCreateCallsMutex.Unlock() + smw.totalCreateCalls += 1 +} + +func (smw *sequencedMockWriter) getTotalCreateCalls() int { + smw.totalCreateCallsMutex.RLock() + defer smw.totalCreateCallsMutex.RUnlock() + return smw.totalCreateCalls +} + +func delayedWriteFunction(delay time.Duration, err error) writeFunction { + return func() error { + time.Sleep(delay) + return err + } +} diff --git a/go/vt/vttablet/tabletserver/dt_executor_test.go b/go/vt/vttablet/tabletserver/dt_executor_test.go index d5322f352f9..f83d7ff9006 100644 --- a/go/vt/vttablet/tabletserver/dt_executor_test.go +++ b/go/vt/vttablet/tabletserver/dt_executor_test.go @@ -31,6 +31,8 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" + "vitess.io/vitess/go/streamlog" + "vitess.io/vitess/go/event/syslogger" "vitess.io/vitess/go/mysql/fakesqldb" "vitess.io/vitess/go/mysql/sqlerror" @@ -705,14 +707,16 @@ func TestNoTwopc(t *testing.T) { want := "2pc is not enabled" for _, tc := range testcases { - err := tc.fun() - require.EqualError(t, err, want) + t.Run(tc.desc, func(t *testing.T) { + err := tc.fun() + require.EqualError(t, err, want) + }) } } func newTestTxExecutor(t *testing.T, ctx context.Context) (txe *DTExecutor, tsv *TabletServer, db *fakesqldb.DB, closer func()) { db = setUpQueryExecutorTest(t) - logStats := tabletenv.NewLogStats(ctx, "TestTxExecutor") + logStats := tabletenv.NewLogStats(ctx, "TestTxExecutor", streamlog.NewQueryLogConfigForTest()) tsv = newTestTabletServer(ctx, smallTxPool, db) cfg := tabletenv.NewDefaultConfig() cfg.DB = newDBConfigs(db) @@ -739,7 +743,7 @@ func newTestTxExecutor(t *testing.T, ctx context.Context) (txe *DTExecutor, tsv // newShortAgeExecutor is same as newTestTxExecutor, but shorter transaction abandon age. func newShortAgeExecutor(t *testing.T, ctx context.Context) (txe *DTExecutor, tsv *TabletServer, db *fakesqldb.DB) { db = setUpQueryExecutorTest(t) - logStats := tabletenv.NewLogStats(ctx, "TestTxExecutor") + logStats := tabletenv.NewLogStats(ctx, "TestTxExecutor", streamlog.NewQueryLogConfigForTest()) tsv = newTestTabletServer(ctx, smallTxPool|shortTwopcAge, db) db.AddQueryPattern("insert into _vt\\.redo_state\\(dtid, state, time_created\\) values \\(_binary'aa', 1,.*", &sqltypes.Result{}) db.AddQueryPattern("insert into _vt\\.redo_statement.*", &sqltypes.Result{}) @@ -756,7 +760,7 @@ func newShortAgeExecutor(t *testing.T, ctx context.Context) (txe *DTExecutor, ts // newNoTwopcExecutor is same as newTestTxExecutor, but 2pc disabled. func newNoTwopcExecutor(t *testing.T, ctx context.Context) (txe *DTExecutor, tsv *TabletServer, db *fakesqldb.DB) { db = setUpQueryExecutorTest(t) - logStats := tabletenv.NewLogStats(ctx, "TestTxExecutor") + logStats := tabletenv.NewLogStats(ctx, "TestTxExecutor", streamlog.NewQueryLogConfigForTest()) tsv = newTestTabletServer(ctx, noTwopc, db) return &DTExecutor{ ctx: ctx, diff --git a/go/vt/vttablet/tabletserver/query_engine.go b/go/vt/vttablet/tabletserver/query_engine.go index d0542165878..4168a11f584 100644 --- a/go/vt/vttablet/tabletserver/query_engine.go +++ b/go/vt/vttablet/tabletserver/query_engine.go @@ -196,6 +196,8 @@ type QueryEngine struct { // Loggers accessCheckerLogger *logutil.ThrottledLogger + + redactUIQuery bool } // NewQueryEngine creates a new QueryEngine. @@ -209,6 +211,7 @@ func NewQueryEngine(env tabletenv.Env, se *schema.Engine) *QueryEngine { se: se, queryRuleSources: rules.NewMap(), enablePerWorkloadTableMetrics: config.EnablePerWorkloadTableMetrics, + redactUIQuery: streamlog.NewQueryLogConfigForTest().RedactDebugUIQueries, } // Cache for query plans: user configured size with a doorkeeper by default to prevent one-off queries @@ -737,7 +740,7 @@ func (qe *QueryEngine) handleHTTPConsolidations(response http.ResponseWriter, re response.Write([]byte(fmt.Sprintf("Length: %d\n", len(items)))) for _, v := range items { var query string - if streamlog.GetRedactDebugUIQueries() { + if qe.redactUIQuery { query, _ = qe.env.Environment().Parser().RedactSQLQuery(v.Query) } else { query = v.Query diff --git a/go/vt/vttablet/tabletserver/query_engine_test.go b/go/vt/vttablet/tabletserver/query_engine_test.go index a1c293ea8ba..c86e8aa163a 100644 --- a/go/vt/vttablet/tabletserver/query_engine_test.go +++ b/go/vt/vttablet/tabletserver/query_engine_test.go @@ -108,7 +108,7 @@ func TestGetPlanPanicDuetoEmptyQuery(t *testing.T) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) _, err := qe.GetPlan(ctx, logStats, "", false) require.EqualError(t, err, "Query was empty") } @@ -195,7 +195,7 @@ func TestQueryPlanCache(t *testing.T) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) initialHits := qe.queryEnginePlanCacheHits.Get() initialMisses := qe.queryEnginePlanCacheMisses.Get() @@ -244,7 +244,7 @@ func TestNoQueryPlanCache(t *testing.T) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) firstPlan, err := qe.GetPlan(ctx, logStats, firstQuery, true) if err != nil { @@ -273,7 +273,7 @@ func TestNoQueryPlanCacheDirective(t *testing.T) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) firstPlan, err := qe.GetPlan(ctx, logStats, firstQuery, false) if err != nil { @@ -301,7 +301,7 @@ func TestStreamQueryPlanCache(t *testing.T) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) firstPlan, err := qe.GetStreamPlan(ctx, logStats, firstQuery, false) require.NoError(t, err) @@ -325,7 +325,7 @@ func TestNoStreamQueryPlanCache(t *testing.T) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) firstPlan, err := qe.GetStreamPlan(ctx, logStats, firstQuery, true) require.NoError(t, err) require.NotNil(t, firstPlan) @@ -349,7 +349,7 @@ func TestNoStreamQueryPlanCacheDirective(t *testing.T) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) firstPlan, err := qe.GetStreamPlan(ctx, logStats, firstQuery, false) require.NoError(t, err) require.NotNil(t, firstPlan) @@ -369,7 +369,7 @@ func TestStatsURL(t *testing.T) { defer qe.Close() // warm up cache ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) qe.GetPlan(ctx, logStats, query, false) request, _ := http.NewRequest("GET", "/debug/tablet_plans", nil) @@ -425,18 +425,12 @@ func runConsolidatedQuery(t *testing.T, sql string) *QueryEngine { } func TestConsolidationsUIRedaction(t *testing.T) { - // Reset to default redaction state. - defer func() { - streamlog.SetRedactDebugUIQueries(false) - }() - request, _ := http.NewRequest("GET", "/debug/consolidations", nil) sql := "select * from test_db_01 where col = 'secret'" redactedSQL := "select * from test_db_01 where col = :col" // First with the redaction off - streamlog.SetRedactDebugUIQueries(false) unRedactedResponse := httptest.NewRecorder() qe := runConsolidatedQuery(t, sql) @@ -446,7 +440,7 @@ func TestConsolidationsUIRedaction(t *testing.T) { } // Now with the redaction on - streamlog.SetRedactDebugUIQueries(true) + qe.redactUIQuery = true redactedResponse := httptest.NewRecorder() qe.handleHTTPConsolidations(redactedResponse, request) @@ -473,7 +467,7 @@ func BenchmarkPlanCacheThroughput(b *testing.B) { defer qe.Close() ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) for i := 0; i < b.N; i++ { query := fmt.Sprintf("SELECT (a, b, c) FROM test_table_%d", rand.IntN(500)) @@ -503,7 +497,7 @@ func benchmarkPlanCache(b *testing.B, db *fakesqldb.DB, par int) { b.SetParallelism(par) b.RunParallel(func(pb *testing.PB) { ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) for pb.Next() { query := fmt.Sprintf("SELECT (a, b, c) FROM test_table_%d", rand.IntN(500)) @@ -618,7 +612,7 @@ func TestPlanCachePollution(t *testing.T) { runner := func(totalQueries uint64, stats *Stats, sample func() string) { for i := uint64(0); i < totalQueries; i++ { ctx := context.Background() - logStats := tabletenv.NewLogStats(ctx, "GetPlanStats") + logStats := tabletenv.NewLogStats(ctx, "GetPlanStats", streamlog.NewQueryLogConfigForTest()) query := sample() start := time.Now() diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index 519b60b79d6..755394723f3 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -69,7 +69,9 @@ type QueryExecutor struct { } const ( - streamRowsSize = 256 + streamRowsSize = 256 + resetLastIDQuery = "select last_insert_id(18446744073709547416)" + resetLastIDValue = 18446744073709547416 ) var ( @@ -716,10 +718,14 @@ func (qre *QueryExecutor) execSelect() (*sqltypes.Result, error) { q.SetErr(err) } } else { - qre.logStats.QuerySources |= tabletenv.QuerySourceConsolidator - startTime := time.Now() - q.Wait() - qre.tsv.stats.WaitTimings.Record("Consolidations", startTime) + waiterCap := qre.tsv.config.ConsolidatorQueryWaiterCap + if waiterCap == 0 || *q.AddWaiterCounter(0) <= waiterCap { + qre.logStats.QuerySources |= tabletenv.QuerySourceConsolidator + startTime := time.Now() + q.Wait() + qre.tsv.stats.WaitTimings.Record("Consolidations", startTime) + } + q.AddWaiterCounter(-1) } if q.Err() != nil { return nil, q.Err() @@ -1111,42 +1117,97 @@ func (qre *QueryExecutor) getSelectLimit() int64 { func (qre *QueryExecutor) execDBConn(conn *connpool.Conn, sql string, wantfields bool) (*sqltypes.Result, error) { span, ctx := trace.NewSpan(qre.ctx, "QueryExecutor.execDBConn") defer span.Finish() - defer qre.logStats.AddRewrittenSQL(sql, time.Now()) qd := NewQueryDetail(qre.logStats.Ctx, conn) - err := qre.tsv.statelessql.Add(qd) - if err != nil { + + if err := qre.tsv.statelessql.Add(qd); err != nil { return nil, err } defer qre.tsv.statelessql.Remove(qd) - return conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err := qre.resetLastInsertIDIfNeeded(ctx, conn); err != nil { + return nil, err + } + + exec, err := conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err != nil { + return nil, err + } + + if err := qre.fetchLastInsertID(ctx, conn, exec); err != nil { + return nil, err + } + + return exec, nil } func (qre *QueryExecutor) execStatefulConn(conn *StatefulConnection, sql string, wantfields bool) (*sqltypes.Result, error) { span, ctx := trace.NewSpan(qre.ctx, "QueryExecutor.execStatefulConn") defer span.Finish() - defer qre.logStats.AddRewrittenSQL(sql, time.Now()) qd := NewQueryDetail(qre.logStats.Ctx, conn) - err := qre.tsv.statefulql.Add(qd) - if err != nil { + + if err := qre.tsv.statefulql.Add(qd); err != nil { return nil, err } defer qre.tsv.statefulql.Remove(qd) - return conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err := qre.resetLastInsertIDIfNeeded(ctx, conn.UnderlyingDBConn().Conn); err != nil { + return nil, err + } + + exec, err := conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err != nil { + return nil, err + } + + if err := qre.fetchLastInsertID(ctx, conn.UnderlyingDBConn().Conn, exec); err != nil { + return nil, err + } + + return exec, nil +} + +func (qre *QueryExecutor) resetLastInsertIDIfNeeded(ctx context.Context, conn *connpool.Conn) error { + if qre.options.GetFetchLastInsertId() { + // if the query contains a last_insert_id(x) function, + // we need to reset the last insert id to check if it was set by the query or not + _, err := conn.Exec(ctx, resetLastIDQuery, 1, false) + if err != nil { + return err + } + } + return nil +} + +func (qre *QueryExecutor) fetchLastInsertID(ctx context.Context, conn *connpool.Conn, exec *sqltypes.Result) error { + if exec.InsertIDUpdated() || !qre.options.GetFetchLastInsertId() { + return nil + } + + result, err := conn.Exec(ctx, "select last_insert_id()", 1, false) + if err != nil { + return err + } + + cell := result.Rows[0][0] + insertID, err := cell.ToCastUint64() + if err != nil { + return err + } + if resetLastIDValue != insertID { + exec.InsertID = insertID + exec.InsertIDChanged = true + } + return nil } func (qre *QueryExecutor) execStreamSQL(conn *connpool.PooledConn, isTransaction bool, sql string, callback func(*sqltypes.Result) error) error { span, ctx := trace.NewSpan(qre.ctx, "QueryExecutor.execStreamSQL") + defer span.Finish() trace.AnnotateSQL(span, sqlparser.Preview(sql)) - callBackClosingSpan := func(result *sqltypes.Result) error { - defer span.Finish() - return callback(result) - } start := time.Now() defer qre.logStats.AddRewrittenSQL(sql, start) @@ -1157,20 +1218,47 @@ func (qre *QueryExecutor) execStreamSQL(conn *connpool.PooledConn, isTransaction // This change will ensure that long-running streaming stateful queries get gracefully shutdown during ServingTypeChange // once their grace period is over. qd := NewQueryDetail(qre.logStats.Ctx, conn.Conn) + + if err := qre.resetLastInsertIDIfNeeded(ctx, conn.Conn); err != nil { + return err + } + + lastInsertIDSet := false + cb := func(result *sqltypes.Result) error { + if result != nil && result.InsertIDUpdated() { + lastInsertIDSet = true + } + return callback(result) + } + + var err error if isTransaction { - err := qre.tsv.statefulql.Add(qd) + err = qre.tsv.statefulql.Add(qd) if err != nil { return err } defer qre.tsv.statefulql.Remove(qd) - return conn.Conn.StreamOnce(ctx, sql, callBackClosingSpan, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) + err = conn.Conn.StreamOnce(ctx, sql, cb, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) + } else { + err = qre.tsv.olapql.Add(qd) + if err != nil { + return err + } + defer qre.tsv.olapql.Remove(qd) + err = conn.Conn.Stream(ctx, sql, cb, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) } - err := qre.tsv.olapql.Add(qd) - if err != nil { + + if err != nil || lastInsertIDSet || !qre.options.GetFetchLastInsertId() { return err } - defer qre.tsv.olapql.Remove(qd) - return conn.Conn.Stream(ctx, sql, callBackClosingSpan, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) + res := &sqltypes.Result{} + if err = qre.fetchLastInsertID(ctx, conn.Conn, res); err != nil { + return err + } + if res.InsertIDUpdated() { + return callback(res) + } + return nil } func (qre *QueryExecutor) recordUserQuery(queryType string, duration int64) { diff --git a/go/vt/vttablet/tabletserver/query_executor_test.go b/go/vt/vttablet/tabletserver/query_executor_test.go index 78daad2e616..6f6becd4038 100644 --- a/go/vt/vttablet/tabletserver/query_executor_test.go +++ b/go/vt/vttablet/tabletserver/query_executor_test.go @@ -28,6 +28,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/streamlog" + "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtenv" @@ -840,7 +842,7 @@ func TestQueryExecutorMessageStreamACL(t *testing.T) { ctx: ctx, query: "stream from msg", plan: plan, - logStats: tabletenv.NewLogStats(ctx, "TestQueryExecutor"), + logStats: tabletenv.NewLogStats(ctx, "TestQueryExecutor", streamlog.NewQueryLogConfigForTest()), tsv: tsv, } @@ -1514,20 +1516,17 @@ func newTestTabletServer(ctx context.Context, flags executorFlags, db *fakesqldb } else { cfg.StrictTableACL = false } - if flags&noTwopc > 0 { - cfg.TwoPCEnable = false - } else { - cfg.TwoPCEnable = true - } if flags&disableOnlineDDL > 0 { cfg.EnableOnlineDDL = false } else { cfg.EnableOnlineDDL = true } - if flags&shortTwopcAge > 0 { - cfg.TwoPCAbandonAge = 0.5 + if flags&noTwopc > 0 { + cfg.TwoPCAbandonAge = 0 + } else if flags&shortTwopcAge > 0 { + cfg.TwoPCAbandonAge = 500 * time.Millisecond } else { - cfg.TwoPCAbandonAge = 10 + cfg.TwoPCAbandonAge = 10 * time.Second } if flags&smallResultSize > 0 { cfg.Oltp.MaxRows = 2 @@ -1559,7 +1558,7 @@ func newTransaction(tsv *TabletServer, options *querypb.ExecuteOptions) int64 { } func newTestQueryExecutor(ctx context.Context, tsv *TabletServer, sql string, txID int64) *QueryExecutor { - logStats := tabletenv.NewLogStats(ctx, "TestQueryExecutor") + logStats := tabletenv.NewLogStats(ctx, "TestQueryExecutor", streamlog.NewQueryLogConfigForTest()) plan, err := tsv.qe.GetPlan(ctx, logStats, sql, false) if err != nil { panic(err) @@ -1576,7 +1575,7 @@ func newTestQueryExecutor(ctx context.Context, tsv *TabletServer, sql string, tx } func newTestQueryExecutorStreaming(ctx context.Context, tsv *TabletServer, sql string, txID int64) *QueryExecutor { - logStats := tabletenv.NewLogStats(ctx, "TestQueryExecutorStreaming") + logStats := tabletenv.NewLogStats(ctx, "TestQueryExecutorStreaming", streamlog.NewQueryLogConfigForTest()) plan, err := tsv.qe.GetStreamPlan(ctx, logStats, sql, false) if err != nil { panic(err) diff --git a/go/vt/vttablet/tabletserver/query_list.go b/go/vt/vttablet/tabletserver/query_list.go index 60fac1ea3af..7263bea3afc 100644 --- a/go/vt/vttablet/tabletserver/query_list.go +++ b/go/vt/vttablet/tabletserver/query_list.go @@ -63,6 +63,8 @@ type QueryList struct { parser *sqlparser.Parser ca ClusterActionState + + redactUIQuery bool } type ClusterActionState int @@ -76,10 +78,11 @@ const ( // NewQueryList creates a new QueryList func NewQueryList(name string, parser *sqlparser.Parser) *QueryList { return &QueryList{ - name: name, - queryDetails: make(map[int64][]*QueryDetail), - parser: parser, - ca: ClusterActionNotInProgress, + name: name, + queryDetails: make(map[int64][]*QueryDetail), + parser: parser, + ca: ClusterActionNotInProgress, + redactUIQuery: streamlog.GetQueryLogConfig().RedactDebugUIQueries, } } @@ -186,7 +189,7 @@ func (ql *QueryList) AppendQueryzRows(rows []QueryDetailzRow) []QueryDetailzRow for _, qds := range ql.queryDetails { for _, qd := range qds { query := qd.conn.Current() - if streamlog.GetRedactDebugUIQueries() { + if ql.redactUIQuery { query, _ = ql.parser.RedactSQLQuery(query) } row := QueryDetailzRow{ diff --git a/go/vt/vttablet/tabletserver/querylogz_test.go b/go/vt/vttablet/tabletserver/querylogz_test.go index ee26437f330..7f865541295 100644 --- a/go/vt/vttablet/tabletserver/querylogz_test.go +++ b/go/vt/vttablet/tabletserver/querylogz_test.go @@ -35,7 +35,7 @@ import ( func TestQuerylogzHandler(t *testing.T) { req, _ := http.NewRequest("GET", "/querylogz?timeout=10&limit=1", nil) - logStats := tabletenv.NewLogStats(context.Background(), "Execute") + logStats := tabletenv.NewLogStats(context.Background(), "Execute", streamlog.NewQueryLogConfigForTest()) logStats.PlanType = planbuilder.PlanSelect.String() logStats.OriginalSQL = "select name, 'inject ' from test_table limit 1000" logStats.RowsAffected = 1000 @@ -144,8 +144,7 @@ func TestQuerylogzHandler(t *testing.T) { checkQuerylogzHasStats(t, slowQueryPattern, logStats, body) // ensure querylogz is not affected by the filter tag - streamlog.SetQueryLogFilterTag("XXX_SKIP_ME") - defer func() { streamlog.SetQueryLogFilterTag("") }() + logStats.Config.FilterTag = "XXX_SKIP_ME" ch = make(chan *tabletenv.LogStats, 1) ch <- logStats querylogzHandler(ch, response, req, sqlparser.NewTestParser()) diff --git a/go/vt/vttablet/tabletserver/rules/cached_size.go b/go/vt/vttablet/tabletserver/rules/cached_size.go index 1375ef2cb7b..d06a31ab8cb 100644 --- a/go/vt/vttablet/tabletserver/rules/cached_size.go +++ b/go/vt/vttablet/tabletserver/rules/cached_size.go @@ -108,6 +108,7 @@ func (cached *bvcre) CachedSize(alloc bool) int64 { } // field re *regexp.Regexp if cached.re != nil { + // WARNING: size of external type regexp.Regexp cannot be fully calculated size += hack.RuntimeAllocSize(int64(160)) } return size @@ -124,6 +125,7 @@ func (cached *namedRegexp) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.name))) // field Regexp *regexp.Regexp if cached.Regexp != nil { + // WARNING: size of external type regexp.Regexp cannot be fully calculated size += hack.RuntimeAllocSize(int64(160)) } return size diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index cae6a237dc8..0ccd0e42735 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -87,18 +87,20 @@ type stateManager struct { // // If a transition fails, we set retrying to true and launch // retryTransition which loops until the state converges. - mu sync.Mutex - wantState servingState - wantTabletType topodatapb.TabletType - state servingState - target *querypb.Target - ptsTimestamp time.Time - retrying bool - replHealthy bool - lameduck bool - alsoAllow []topodatapb.TabletType - reason string - transitionErr error + mu sync.Mutex + wantState servingState + wantTabletType topodatapb.TabletType + state servingState + target *querypb.Target + ptsTimestamp time.Time + retrying bool + replHealthy bool + demotePrimaryStalled bool + lameduck bool + diskHealthMonitor DiskHealthMonitor + alsoAllow []topodatapb.TabletType + reason string + transitionErr error rw *requestsWaiter @@ -387,7 +389,7 @@ func (sm *stateManager) StartRequest(ctx context.Context, target *querypb.Target sm.mu.Lock() defer sm.mu.Unlock() - if sm.state != StateServing || !sm.replHealthy { + if sm.state != StateServing || !sm.replHealthy || sm.demotePrimaryStalled { // This specific error string needs to be returned for vtgate buffering to work. return vterrors.New(vtrpcpb.Code_CLUSTER_EVENT, vterrors.NotServing) } @@ -715,6 +717,10 @@ func (sm *stateManager) Broadcast() { defer sm.mu.Unlock() lag, err := sm.refreshReplHealthLocked() + if sm.demotePrimaryStalled { + // If we are stalled while demoting primary, we should send an error for it. + err = vterrors.VT09031() + } sm.hs.ChangeState(sm.target.TabletType, sm.ptsTimestamp, lag, err, sm.isServingLocked()) } @@ -772,7 +778,7 @@ func (sm *stateManager) IsServing() bool { } func (sm *stateManager) isServingLocked() bool { - return sm.state == StateServing && sm.wantState == StateServing && sm.replHealthy && !sm.lameduck + return sm.state == StateServing && sm.wantState == StateServing && sm.replHealthy && !sm.demotePrimaryStalled && !sm.lameduck && !sm.diskHealthMonitor.IsDiskStalled() } func (sm *stateManager) AppendDetails(details []*kv) []*kv { diff --git a/go/vt/vttablet/tabletserver/state_manager_test.go b/go/vt/vttablet/tabletserver/state_manager_test.go index df819c6f05c..99a3e7e681d 100644 --- a/go/vt/vttablet/tabletserver/state_manager_test.go +++ b/go/vt/vttablet/tabletserver/state_manager_test.go @@ -41,7 +41,9 @@ import ( var testNow = time.Now() func TestStateManagerStateByName(t *testing.T) { - sm := &stateManager{} + sm := &stateManager{ + diskHealthMonitor: newNoopDiskHealthMonitor(), + } sm.replHealthy = true sm.wantState = StateServing @@ -147,6 +149,29 @@ func TestStateManagerUnservePrimary(t *testing.T) { assert.Equal(t, StateNotServing, sm.state) } +type testDiskMonitor struct { + isDiskStalled bool +} + +func (t *testDiskMonitor) IsDiskStalled() bool { + return t.isDiskStalled +} + +// TestIsServingLocked tests isServingLocked() functionality. +func TestIsServingLocked(t *testing.T) { + sm := newTestStateManager() + defer sm.StopService() + tdm := &testDiskMonitor{isDiskStalled: false} + sm.diskHealthMonitor = tdm + + err := sm.SetServingType(topodatapb.TabletType_REPLICA, testNow, StateServing, "") + require.NoError(t, err) + require.True(t, sm.isServingLocked()) + + tdm.isDiskStalled = true + require.False(t, sm.isServingLocked()) +} + func TestStateManagerUnserveNonPrimary(t *testing.T) { sm := newTestStateManager() defer sm.StopService() @@ -669,6 +694,45 @@ func TestStateManagerNotify(t *testing.T) { sm.StopService() } +func TestDemotePrimaryStalled(t *testing.T) { + sm := newTestStateManager() + defer sm.StopService() + err := sm.SetServingType(topodatapb.TabletType_PRIMARY, testNow, StateServing, "") + require.NoError(t, err) + // Stopping the ticker so that we don't get unexpected health streams. + sm.hcticks.Stop() + + ch := make(chan *querypb.StreamHealthResponse, 5) + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + err := sm.hs.Stream(context.Background(), func(shr *querypb.StreamHealthResponse) error { + ch <- shr + return nil + }) + assert.Contains(t, err.Error(), "tabletserver is shutdown") + }() + defer wg.Wait() + + // Send a broadcast message and check we have no error there. + sm.Broadcast() + gotshr := <-ch + require.Empty(t, gotshr.RealtimeStats.HealthError) + + // If demote primary is stalled, then we should get an error. + sm.demotePrimaryStalled = true + sm.Broadcast() + gotshr = <-ch + require.EqualValues(t, "VT09031: Primary demotion is stalled", gotshr.RealtimeStats.HealthError) + // Verify that we can't start a new request once we have a demote primary stalled. + err = sm.StartRequest(context.Background(), &querypb.Target{TabletType: topodatapb.TabletType_PRIMARY}, false) + require.ErrorContains(t, err, "operation not allowed in state NOT_SERVING") + + // Stop the state manager. + sm.StopService() +} + func TestRefreshReplHealthLocked(t *testing.T) { sm := newTestStateManager() defer sm.StopService() @@ -739,23 +803,24 @@ func newTestStateManager() *stateManager { parser := sqlparser.NewTestParser() env := tabletenv.NewEnv(vtenv.NewTestEnv(), cfg, "StateManagerTest") sm := &stateManager{ - statelessql: NewQueryList("stateless", parser), - statefulql: NewQueryList("stateful", parser), - olapql: NewQueryList("olap", parser), - hs: newHealthStreamer(env, &topodatapb.TabletAlias{}, schema.NewEngine(env)), - se: &testSchemaEngine{}, - rt: &testReplTracker{lag: 1 * time.Second}, - vstreamer: &testSubcomponent{}, - tracker: &testSubcomponent{}, - watcher: &testSubcomponent{}, - qe: &testQueryEngine{}, - txThrottler: &testTxThrottler{}, - te: &testTxEngine{}, - messager: &testSubcomponent{}, - ddle: &testOnlineDDLExecutor{}, - throttler: &testLagThrottler{}, - tableGC: &testTableGC{}, - rw: newRequestsWaiter(), + statelessql: NewQueryList("stateless", parser), + statefulql: NewQueryList("stateful", parser), + olapql: NewQueryList("olap", parser), + hs: newHealthStreamer(env, &topodatapb.TabletAlias{}, schema.NewEngine(env)), + se: &testSchemaEngine{}, + rt: &testReplTracker{lag: 1 * time.Second}, + vstreamer: &testSubcomponent{}, + tracker: &testSubcomponent{}, + watcher: &testSubcomponent{}, + qe: &testQueryEngine{}, + txThrottler: &testTxThrottler{}, + te: &testTxEngine{}, + messager: &testSubcomponent{}, + ddle: &testOnlineDDLExecutor{}, + diskHealthMonitor: newNoopDiskHealthMonitor(), + throttler: &testLagThrottler{}, + tableGC: &testTableGC{}, + rw: newRequestsWaiter(), } sm.Init(env, &querypb.Target{}) sm.hs.InitDBConfig(&querypb.Target{}) diff --git a/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go b/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go index caa519cc477..c8d9f634384 100644 --- a/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go +++ b/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + "vitess.io/vitess/go/streamlog" querypb "vitess.io/vitess/go/vt/proto/query" "github.com/stretchr/testify/require" @@ -126,7 +127,7 @@ func (ct *consolidationTest) run(workers int, generateCallback func(int) (string defer wg.Done() exporter := servenv.NewExporter("ConsolidatorTest", "") timings := exporter.NewTimings("ConsolidatorWaits", "", "StreamConsolidations") - logStats := tabletenv.NewLogStats(context.Background(), "StreamConsolidation") + logStats := tabletenv.NewLogStats(context.Background(), "StreamConsolidation", streamlog.NewQueryLogConfigForTest()) query, callback := generateCallback(worker) start := time.Now() err := ct.cc.Consolidate(timings, logStats, query, func(result *sqltypes.Result) error { diff --git a/go/vt/vttablet/tabletserver/tabletenv/config.go b/go/vt/vttablet/tabletserver/tabletenv/config.go index 158f40d5202..ddab935d393 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/config.go +++ b/go/vt/vttablet/tabletserver/tabletenv/config.go @@ -143,6 +143,9 @@ func registerTabletEnvFlags(fs *pflag.FlagSet) { fs.DurationVar(¤tConfig.OltpReadPool.Timeout, "queryserver-config-query-pool-timeout", defaultConfig.OltpReadPool.Timeout, "query server query pool timeout, it is how long vttablet waits for a connection from the query pool. If set to 0 (default) then the overall query timeout is used instead.") fs.DurationVar(¤tConfig.OlapReadPool.Timeout, "queryserver-config-stream-pool-timeout", defaultConfig.OlapReadPool.Timeout, "query server stream pool timeout, it is how long vttablet waits for a connection from the stream pool. If set to 0 (default) then there is no timeout.") fs.DurationVar(¤tConfig.TxPool.Timeout, "queryserver-config-txpool-timeout", defaultConfig.TxPool.Timeout, "query server transaction pool timeout, it is how long vttablet waits if tx pool is full") + fs.IntVar(¤tConfig.OltpReadPool.MaxIdleCount, "queryserver-config-query-pool-max-idle-count", defaultConfig.OltpReadPool.MaxIdleCount, "query server query pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods.") + fs.IntVar(¤tConfig.OlapReadPool.MaxIdleCount, "queryserver-config-stream-pool-max-idle-count", defaultConfig.OlapReadPool.MaxIdleCount, "query server stream pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods.") + fs.IntVar(¤tConfig.TxPool.MaxIdleCount, "queryserver-config-txpool-max-idle-count", defaultConfig.TxPool.MaxIdleCount, "query server transaction pool - maximum number of idle connections to retain in the pool. Use this to balance between faster response times during traffic bursts and resource efficiency during low-traffic periods.") fs.DurationVar(¤tConfig.OltpReadPool.IdleTimeout, "queryserver-config-idle-timeout", defaultConfig.OltpReadPool.IdleTimeout, "query server idle timeout, vttablet manages various mysql connection pools. This config means if a connection has not been used in given idle timeout, this connection will be removed from pool. This effectively manages number of connection objects and optimize the pool performance.") fs.DurationVar(¤tConfig.OltpReadPool.MaxLifetime, "queryserver-config-pool-conn-max-lifetime", defaultConfig.OltpReadPool.MaxLifetime, "query server connection max lifetime, vttablet manages various mysql connection pools. This config means if a connection has lived at least this long, it connection will be removed from pool upon the next time it is returned to the pool.") @@ -156,8 +159,12 @@ func registerTabletEnvFlags(fs *pflag.FlagSet) { fs.BoolVar(¤tConfig.WatchReplication, "watch_replication_stream", false, "When enabled, vttablet will stream the MySQL replication stream from the local server, and use it to update schema when it sees a DDL.") fs.BoolVar(¤tConfig.TrackSchemaVersions, "track_schema_versions", false, "When enabled, vttablet will store versions of schemas at each position that a DDL is applied and allow retrieval of the schema corresponding to a position") fs.Int64Var(¤tConfig.SchemaVersionMaxAgeSeconds, "schema-version-max-age-seconds", 0, "max age of schema version records to kept in memory by the vreplication historian") - fs.BoolVar(¤tConfig.TwoPCEnable, "twopc_enable", defaultConfig.TwoPCEnable, "if the flag is on, 2pc is enabled. Other 2pc flags must be supplied.") - SecondsVar(fs, ¤tConfig.TwoPCAbandonAge, "twopc_abandon_age", defaultConfig.TwoPCAbandonAge, "time in seconds. Any unresolved transaction older than this time will be sent to the coordinator to be resolved.") + + _ = fs.Bool("twopc_enable", true, "TwoPC is enabled") + _ = fs.MarkDeprecated("twopc_enable", "TwoPC is always enabled, the transaction abandon age can be configured") + flagutil.FloatDuration(fs, ¤tConfig.TwoPCAbandonAge, "twopc_abandon_age", defaultConfig.TwoPCAbandonAge, + "Any unresolved transaction older than this time will be sent to the coordinator to be resolved. NOTE: Providing time as seconds (float64) is deprecated. Use time.Duration format (e.g., '1s', '2m', '1h').") + // Tx throttler config flagutil.DualFormatBoolVar(fs, ¤tConfig.EnableTxThrottler, "enable_tx_throttler", defaultConfig.EnableTxThrottler, "If true replication-lag-based throttling on transactions will be enabled.") flagutil.DualFormatVar(fs, currentConfig.TxThrottlerConfig, "tx_throttler_config", "The configuration of the transaction throttler as a text-formatted throttlerdata.Configuration protocol buffer message.") @@ -191,6 +198,7 @@ func registerTabletEnvFlags(fs *pflag.FlagSet) { fs.Int64Var(¤tConfig.ConsolidatorStreamQuerySize, "consolidator-stream-query-size", defaultConfig.ConsolidatorStreamQuerySize, "Configure the stream consolidator query size in bytes. Setting to 0 disables the stream consolidator.") fs.Int64Var(¤tConfig.ConsolidatorStreamTotalSize, "consolidator-stream-total-size", defaultConfig.ConsolidatorStreamTotalSize, "Configure the stream consolidator total size in bytes. Setting to 0 disables the stream consolidator.") + fs.Int64Var(¤tConfig.ConsolidatorQueryWaiterCap, "consolidator-query-waiter-cap", 0, "Configure the maximum number of clients allowed to wait on the consolidator.") fs.DurationVar(&healthCheckInterval, "health_check_interval", defaultConfig.Healthcheck.Interval, "Interval between health checks") fs.DurationVar(°radedThreshold, "degraded_threshold", defaultConfig.Healthcheck.DegradedThreshold, "replication lag after which a replica is considered degraded") fs.DurationVar(&unhealthyThreshold, "unhealthy_threshold", defaultConfig.Healthcheck.UnhealthyThreshold, "replication lag after which a replica is considered unhealthy") @@ -271,11 +279,12 @@ func Init() { currentConfig.Healthcheck.UnhealthyThreshold = unhealthyThreshold currentConfig.GracePeriods.Transition = transitionGracePeriod - switch streamlog.GetQueryLogFormat() { + logFormat := streamlog.GetQueryLogConfig().Format + switch logFormat { case streamlog.QueryLogFormatText: case streamlog.QueryLogFormatJSON: default: - log.Exitf("Invalid querylog-format value %v: must be either text or json", streamlog.GetQueryLogFormat()) + log.Exitf("Invalid querylog-format value %v: must be either text or json", logFormat) } if queryLogHandler != "" { @@ -316,6 +325,7 @@ type TabletConfig struct { StreamBufferSize int `json:"streamBufferSize,omitempty"` ConsolidatorStreamTotalSize int64 `json:"consolidatorStreamTotalSize,omitempty"` ConsolidatorStreamQuerySize int64 `json:"consolidatorStreamQuerySize,omitempty"` + ConsolidatorQueryWaiterCap int64 `json:"consolidatorMaxQueryWait,omitempty"` QueryCacheMemory int64 `json:"queryCacheMemory,omitempty"` QueryCacheDoorkeeper bool `json:"queryCacheDoorkeeper,omitempty"` SchemaReloadInterval time.Duration `json:"schemaReloadIntervalSeconds,omitempty"` @@ -331,12 +341,11 @@ type TabletConfig struct { ExternalConnections map[string]*dbconfigs.DBConfigs `json:"externalConnections,omitempty"` - SanitizeLogMessages bool `json:"-"` - StrictTableACL bool `json:"-"` - EnableTableACLDryRun bool `json:"-"` - TableACLExemptACL string `json:"-"` - TwoPCEnable bool `json:"-"` - TwoPCAbandonAge Seconds `json:"-"` + SanitizeLogMessages bool `json:"-"` + StrictTableACL bool `json:"-"` + EnableTableACLDryRun bool `json:"-"` + TableACLExemptACL string `json:"-"` + TwoPCAbandonAge time.Duration `json:"-"` EnableTxThrottler bool `json:"-"` TxThrottlerConfig *TxThrottlerConfigFlag `json:"-"` @@ -421,6 +430,7 @@ type ConnPoolConfig struct { Size int `json:"size,omitempty"` Timeout time.Duration `json:"timeoutSeconds,omitempty"` IdleTimeout time.Duration `json:"idleTimeoutSeconds,omitempty"` + MaxIdleCount int `json:"maxIdleCount,omitempty"` MaxLifetime time.Duration `json:"maxLifetimeSeconds,omitempty"` PrefillParallelism int `json:"prefillParallelism,omitempty"` } @@ -430,9 +440,10 @@ func (cfg *ConnPoolConfig) MarshalJSON() ([]byte, error) { tmp := struct { Proxy - Timeout string `json:"timeoutSeconds,omitempty"` - IdleTimeout string `json:"idleTimeoutSeconds,omitempty"` - MaxLifetime string `json:"maxLifetimeSeconds,omitempty"` + Timeout string `json:"timeoutSeconds,omitempty"` + IdleTimeout string `json:"idleTimeoutSeconds,omitempty"` + MaxIdleCount int `json:"maxIdleCount,omitempty"` + MaxLifetime string `json:"maxLifetimeSeconds,omitempty"` }{ Proxy: Proxy(*cfg), } @@ -457,6 +468,7 @@ func (cfg *ConnPoolConfig) UnmarshalJSON(data []byte) (err error) { Size int `json:"size,omitempty"` Timeout string `json:"timeoutSeconds,omitempty"` IdleTimeout string `json:"idleTimeoutSeconds,omitempty"` + MaxIdleCount int `json:"maxIdleCount,omitempty"` MaxLifetime string `json:"maxLifetimeSeconds,omitempty"` PrefillParallelism int `json:"prefillParallelism,omitempty"` } @@ -487,6 +499,7 @@ func (cfg *ConnPoolConfig) UnmarshalJSON(data []byte) (err error) { } cfg.Size = tmp.Size + cfg.MaxIdleCount = tmp.MaxIdleCount cfg.PrefillParallelism = tmp.PrefillParallelism return nil @@ -1054,6 +1067,8 @@ var defaultConfig = TabletConfig{ }, EnablePerWorkloadTableMetrics: false, + + TwoPCAbandonAge: 15 * time.Minute, } // defaultTxThrottlerConfig returns the default TxThrottlerConfigFlag object based on diff --git a/go/vt/vttablet/tabletserver/tabletenv/config_test.go b/go/vt/vttablet/tabletserver/tabletenv/config_test.go index d16b6276964..9ae653bafb9 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/config_test.go +++ b/go/vt/vttablet/tabletserver/tabletenv/config_test.go @@ -28,13 +28,12 @@ import ( "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/mysqlctl" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/throttler" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/yaml2" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) func TestConfigParse(t *testing.T) { @@ -49,10 +48,11 @@ func TestConfigParse(t *testing.T) { }, }, OltpReadPool: ConnPoolConfig{ - Size: 16, - Timeout: 10 * time.Second, - IdleTimeout: 20 * time.Second, - MaxLifetime: 50 * time.Second, + Size: 16, + Timeout: 10 * time.Second, + IdleTimeout: 20 * time.Second, + MaxLifetime: 50 * time.Second, + MaxIdleCount: 8, }, RowStreamer: RowStreamerConfig{ MaxInnoDBTrxHistLen: 1000, @@ -113,6 +113,7 @@ txPool: {} oltpReadPool: size: 16 idleTimeoutSeconds: 20s + maxIdleCount: 8 maxLifetimeSeconds: 50s `) gotCfg := cfg diff --git a/go/vt/vttablet/tabletserver/tabletenv/logstats.go b/go/vt/vttablet/tabletserver/tabletenv/logstats.go index ad7e09de169..40156f3bcdc 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/logstats.go +++ b/go/vt/vttablet/tabletserver/tabletenv/logstats.go @@ -43,6 +43,8 @@ const ( // LogStats records the stats for a single query type LogStats struct { + Config streamlog.QueryLogConfig + Ctx context.Context Method string Target *querypb.Target @@ -66,11 +68,12 @@ type LogStats struct { // NewLogStats constructs a new LogStats with supplied Method and ctx // field values, and the StartTime field set to the present time. -func NewLogStats(ctx context.Context, methodName string) *LogStats { +func NewLogStats(ctx context.Context, methodName string, config streamlog.QueryLogConfig) *LogStats { return &LogStats{ Ctx: ctx, Method: methodName, StartTime: time.Now(), + Config: config, } } @@ -177,17 +180,16 @@ func (stats *LogStats) CallInfo() (string, string) { // Logf formats the log record to the given writer, either as // tab-separated list of logged fields or as JSON. func (stats *LogStats) Logf(w io.Writer, params url.Values) error { - if !streamlog.ShouldEmitLog(stats.OriginalSQL, uint64(stats.RowsAffected), uint64(len(stats.Rows))) { + if !stats.Config.ShouldEmitLog(stats.OriginalSQL, uint64(stats.RowsAffected), uint64(len(stats.Rows)), stats.Error != nil) { return nil } - redacted := streamlog.GetRedactDebugUIQueries() _, fullBindParams := params["full"] // TODO: remove username here we fully enforce immediate caller id callInfo, username := stats.CallInfo() log := logstats.NewLogger() - log.Init(streamlog.GetQueryLogFormat() == streamlog.QueryLogFormatJSON) + log.Init(stats.Config.Format == streamlog.QueryLogFormatJSON) log.Key("Method") log.StringUnquoted(stats.Method) log.Key("CallInfo") @@ -209,7 +211,7 @@ func (stats *LogStats) Logf(w io.Writer, params url.Values) error { log.Key("OriginalSQL") log.String(stats.OriginalSQL) log.Key("BindVars") - if redacted { + if stats.Config.RedactDebugUIQueries { log.Redacted() } else { log.BindVariables(stats.BindVariables, fullBindParams) @@ -217,7 +219,7 @@ func (stats *LogStats) Logf(w io.Writer, params url.Values) error { log.Key("Queries") log.Int(int64(stats.NumberOfQueries)) log.Key("RewrittenSQL") - if redacted { + if stats.Config.RedactDebugUIQueries { log.Redacted() } else { log.String(stats.RewrittenSQL()) diff --git a/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go b/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go index 7412a0a436c..4c31b890cca 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go +++ b/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go @@ -26,6 +26,8 @@ import ( "time" "github.com/google/safehtml/testconversions" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/streamlog" @@ -35,7 +37,7 @@ import ( ) func TestLogStats(t *testing.T) { - logStats := NewLogStats(context.Background(), "test") + logStats := NewLogStats(context.Background(), "test", streamlog.QueryLogConfig{}) logStats.AddRewrittenSQL("sql1", time.Now()) if !strings.Contains(logStats.RewrittenSQL(), "sql1") { @@ -59,7 +61,7 @@ func testFormat(stats *LogStats, params url.Values) string { } func TestLogStatsFormat(t *testing.T) { - logStats := NewLogStats(context.Background(), "test") + logStats := NewLogStats(context.Background(), "test", streamlog.NewQueryLogConfigForTest()) logStats.StartTime = time.Date(2017, time.January, 1, 1, 2, 3, 0, time.UTC) logStats.EndTime = time.Date(2017, time.January, 1, 1, 2, 4, 1234, time.UTC) logStats.OriginalSQL = "sql" @@ -70,90 +72,65 @@ func TestLogStatsFormat(t *testing.T) { logStats.Rows = [][]sqltypes.Value{{sqltypes.NewVarBinary("a")}} params := map[string][]string{"full": {}} - streamlog.SetRedactDebugUIQueries(false) - streamlog.SetQueryLogFormat("text") - got := testFormat(logStats, url.Values(params)) + got := testFormat(logStats, params) want := "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t\t\"sql\"\t{\"intVal\": {\"type\": \"INT64\", \"value\": 1}}\t1\t\"sql with pii\"\tmysql\t0.000000\t0.000000\t0\t12345\t1\t\"\"\t\n" - if got != want { - t.Errorf("logstats format: got:\n%q\nwant:\n%q\n", got, want) - } + assert.Equal(t, want, got) - streamlog.SetRedactDebugUIQueries(true) - streamlog.SetQueryLogFormat("text") - got = testFormat(logStats, url.Values(params)) + logStats.Config.RedactDebugUIQueries = true + + got = testFormat(logStats, params) want = "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t\t\"sql\"\t\"[REDACTED]\"\t1\t\"[REDACTED]\"\tmysql\t0.000000\t0.000000\t0\t12345\t1\t\"\"\t\n" - if got != want { - t.Errorf("logstats format: got:\n%q\nwant:\n%q\n", got, want) - } + assert.Equal(t, want, got) - streamlog.SetRedactDebugUIQueries(false) - streamlog.SetQueryLogFormat("json") - got = testFormat(logStats, url.Values(params)) + logStats.Config.RedactDebugUIQueries = false + logStats.Config.Format = streamlog.QueryLogFormatJSON + + got = testFormat(logStats, params) var parsed map[string]any err := json.Unmarshal([]byte(got), &parsed) if err != nil { t.Errorf("logstats format: error unmarshaling json: %v -- got:\n%v", err, got) } formatted, err := json.MarshalIndent(parsed, "", " ") - if err != nil { - t.Errorf("logstats format: error marshaling json: %v -- got:\n%v", err, got) - } + require.NoError(t, err) want = "{\n \"BindVars\": {\n \"intVal\": {\n \"type\": \"INT64\",\n \"value\": 1\n }\n },\n \"CallInfo\": \"\",\n \"ConnWaitTime\": 0,\n \"Effective Caller\": \"\",\n \"End\": \"2017-01-01 01:02:04.000001\",\n \"Error\": \"\",\n \"ImmediateCaller\": \"\",\n \"Method\": \"test\",\n \"MysqlTime\": 0,\n \"OriginalSQL\": \"sql\",\n \"PlanType\": \"\",\n \"Queries\": 1,\n \"QuerySources\": \"mysql\",\n \"ResponseSize\": 1,\n \"RewrittenSQL\": \"sql with pii\",\n \"RowsAffected\": 0,\n \"Start\": \"2017-01-01 01:02:03.000000\",\n \"TotalTime\": 1.000001,\n \"TransactionID\": 12345,\n \"Username\": \"\"\n}" - if string(formatted) != want { - t.Errorf("logstats format: got:\n%q\nwant:\n%v\n", string(formatted), want) - } + assert.Equal(t, want, string(formatted)) + + logStats.Config.RedactDebugUIQueries = true + logStats.Config.Format = streamlog.QueryLogFormatJSON - streamlog.SetRedactDebugUIQueries(true) - streamlog.SetQueryLogFormat("json") - got = testFormat(logStats, url.Values(params)) + got = testFormat(logStats, params) err = json.Unmarshal([]byte(got), &parsed) - if err != nil { - t.Errorf("logstats format: error unmarshaling json: %v -- got:\n%v", err, got) - } + require.NoError(t, err) formatted, err = json.MarshalIndent(parsed, "", " ") - if err != nil { - t.Errorf("logstats format: error marshaling json: %v -- got:\n%v", err, got) - } + require.NoError(t, err) want = "{\n \"BindVars\": \"[REDACTED]\",\n \"CallInfo\": \"\",\n \"ConnWaitTime\": 0,\n \"Effective Caller\": \"\",\n \"End\": \"2017-01-01 01:02:04.000001\",\n \"Error\": \"\",\n \"ImmediateCaller\": \"\",\n \"Method\": \"test\",\n \"MysqlTime\": 0,\n \"OriginalSQL\": \"sql\",\n \"PlanType\": \"\",\n \"Queries\": 1,\n \"QuerySources\": \"mysql\",\n \"ResponseSize\": 1,\n \"RewrittenSQL\": \"[REDACTED]\",\n \"RowsAffected\": 0,\n \"Start\": \"2017-01-01 01:02:03.000000\",\n \"TotalTime\": 1.000001,\n \"TransactionID\": 12345,\n \"Username\": \"\"\n}" - if string(formatted) != want { - t.Errorf("logstats format: got:\n%q\nwant:\n%v\n", string(formatted), want) - } - - streamlog.SetRedactDebugUIQueries(false) + assert.Equal(t, want, string(formatted)) // Make sure formatting works for string bind vars. We can't do this as part of a single // map because the output ordering is undefined. logStats.BindVariables = map[string]*querypb.BindVariable{"strVal": sqltypes.StringBindVariable("abc")} + logStats.Config.RedactDebugUIQueries = false + logStats.Config.Format = streamlog.QueryLogFormatText - streamlog.SetQueryLogFormat("text") - got = testFormat(logStats, url.Values(params)) + got = testFormat(logStats, params) want = "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t\t\"sql\"\t{\"strVal\": {\"type\": \"VARCHAR\", \"value\": \"abc\"}}\t1\t\"sql with pii\"\tmysql\t0.000000\t0.000000\t0\t12345\t1\t\"\"\t\n" - if got != want { - t.Errorf("logstats format: got:\n%q\nwant:\n%q\n", got, want) - } + assert.Equal(t, want, got) + + logStats.Config.RedactDebugUIQueries = false + logStats.Config.Format = streamlog.QueryLogFormatJSON - streamlog.SetQueryLogFormat("json") - got = testFormat(logStats, url.Values(params)) + got = testFormat(logStats, params) err = json.Unmarshal([]byte(got), &parsed) - if err != nil { - t.Errorf("logstats format: error unmarshaling json: %v -- got:\n%v", err, got) - } + require.NoError(t, err) formatted, err = json.MarshalIndent(parsed, "", " ") - if err != nil { - t.Errorf("logstats format: error marshaling json: %v -- got:\n%v", err, got) - } + require.NoError(t, err) want = "{\n \"BindVars\": {\n \"strVal\": {\n \"type\": \"VARCHAR\",\n \"value\": \"abc\"\n }\n },\n \"CallInfo\": \"\",\n \"ConnWaitTime\": 0,\n \"Effective Caller\": \"\",\n \"End\": \"2017-01-01 01:02:04.000001\",\n \"Error\": \"\",\n \"ImmediateCaller\": \"\",\n \"Method\": \"test\",\n \"MysqlTime\": 0,\n \"OriginalSQL\": \"sql\",\n \"PlanType\": \"\",\n \"Queries\": 1,\n \"QuerySources\": \"mysql\",\n \"ResponseSize\": 1,\n \"RewrittenSQL\": \"sql with pii\",\n \"RowsAffected\": 0,\n \"Start\": \"2017-01-01 01:02:03.000000\",\n \"TotalTime\": 1.000001,\n \"TransactionID\": 12345,\n \"Username\": \"\"\n}" - if string(formatted) != want { - t.Errorf("logstats format: got:\n%q\nwant:\n%v\n", string(formatted), want) - } - - streamlog.SetQueryLogFormat("text") + assert.Equal(t, want, string(formatted)) } func TestLogStatsFilter(t *testing.T) { - defer func() { streamlog.SetQueryLogFilterTag("") }() - - logStats := NewLogStats(context.Background(), "test") + logStats := NewLogStats(context.Background(), "test", streamlog.NewQueryLogConfigForTest()) logStats.StartTime = time.Date(2017, time.January, 1, 1, 2, 3, 0, time.UTC) logStats.EndTime = time.Date(2017, time.January, 1, 1, 2, 4, 1234, time.UTC) logStats.OriginalSQL = "sql /* LOG_THIS_QUERY */" @@ -163,21 +140,21 @@ func TestLogStatsFilter(t *testing.T) { logStats.Rows = [][]sqltypes.Value{{sqltypes.NewVarBinary("a")}} params := map[string][]string{"full": {}} - got := testFormat(logStats, url.Values(params)) + got := testFormat(logStats, params) want := "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t\t\"sql /* LOG_THIS_QUERY */\"\t{\"intVal\": {\"type\": \"INT64\", \"value\": 1}}\t1\t\"sql with pii\"\tmysql\t0.000000\t0.000000\t0\t0\t1\t\"\"\t\n" if got != want { t.Errorf("logstats format: got:\n%q\nwant:\n%q\n", got, want) } - streamlog.SetQueryLogFilterTag("LOG_THIS_QUERY") - got = testFormat(logStats, url.Values(params)) + logStats.Config.FilterTag = "LOG_THIS_QUERY" + got = testFormat(logStats, params) want = "test\t\t\t''\t''\t2017-01-01 01:02:03.000000\t2017-01-01 01:02:04.000001\t1.000001\t\t\"sql /* LOG_THIS_QUERY */\"\t{\"intVal\": {\"type\": \"INT64\", \"value\": 1}}\t1\t\"sql with pii\"\tmysql\t0.000000\t0.000000\t0\t0\t1\t\"\"\t\n" if got != want { t.Errorf("logstats format: got:\n%q\nwant:\n%q\n", got, want) } - streamlog.SetQueryLogFilterTag("NOT_THIS_QUERY") - got = testFormat(logStats, url.Values(params)) + logStats.Config.FilterTag = "NOT_THIS_QUERY" + got = testFormat(logStats, params) want = "" if got != want { t.Errorf("logstats format: got:\n%q\nwant:\n%q\n", got, want) @@ -185,7 +162,7 @@ func TestLogStatsFilter(t *testing.T) { } func TestLogStatsFormatQuerySources(t *testing.T) { - logStats := NewLogStats(context.Background(), "test") + logStats := NewLogStats(context.Background(), "test", streamlog.NewQueryLogConfigForTest()) if logStats.FmtQuerySources() != "none" { t.Fatalf("should return none since log stats does not have any query source, but got: %s", logStats.FmtQuerySources()) } @@ -207,14 +184,14 @@ func TestLogStatsContextHTML(t *testing.T) { Html: testconversions.MakeHTMLForTest(html), } ctx := callinfo.NewContext(context.Background(), callInfo) - logStats := NewLogStats(ctx, "test") + logStats := NewLogStats(ctx, "test", streamlog.NewQueryLogConfigForTest()) if logStats.ContextHTML().String() != html { t.Fatalf("expect to get html: %s, but got: %s", html, logStats.ContextHTML().String()) } } func TestLogStatsErrorStr(t *testing.T) { - logStats := NewLogStats(context.Background(), "test") + logStats := NewLogStats(context.Background(), "test", streamlog.NewQueryLogConfigForTest()) if logStats.ErrorStr() != "" { t.Fatalf("should not get error in stats, but got: %s", logStats.ErrorStr()) } @@ -226,7 +203,7 @@ func TestLogStatsErrorStr(t *testing.T) { } func TestLogStatsCallInfo(t *testing.T) { - logStats := NewLogStats(context.Background(), "test") + logStats := NewLogStats(context.Background(), "test", streamlog.NewQueryLogConfigForTest()) caller, user := logStats.CallInfo() if caller != "" { t.Fatalf("caller should be empty") @@ -243,7 +220,7 @@ func TestLogStatsCallInfo(t *testing.T) { User: username, } ctx := callinfo.NewContext(context.Background(), callInfo) - logStats = NewLogStats(ctx, "test") + logStats = NewLogStats(ctx, "test", streamlog.NewQueryLogConfigForTest()) caller, user = logStats.CallInfo() wantCaller := remoteAddr + ":FakeExecute(fakeRPC)" if caller != wantCaller { @@ -253,3 +230,18 @@ func TestLogStatsCallInfo(t *testing.T) { t.Fatalf("expected to get username: %s, but got: %s", username, user) } } + +// TestLogStatsErrorsOnly tests that LogStats only logs errors when the query log mode is set to errors only for VTTablet. +func TestLogStatsErrorsOnly(t *testing.T) { + logStats := NewLogStats(context.Background(), "test", streamlog.NewQueryLogConfigForTest()) + logStats.Config.Mode = streamlog.QueryLogModeError + + // no error, should not log + logOutput := testFormat(logStats, url.Values{}) + assert.Empty(t, logOutput) + + // error, should log + logStats.Error = errors.New("test error") + logOutput = testFormat(logStats, url.Values{}) + assert.Contains(t, logOutput, "test error") +} diff --git a/go/vt/vttablet/tabletserver/tabletenv/seconds.go b/go/vt/vttablet/tabletserver/tabletenv/seconds.go deleted file mode 100644 index ae11121f2de..00000000000 --- a/go/vt/vttablet/tabletserver/tabletenv/seconds.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2020 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 tabletenv - -import ( - "time" - - "github.com/spf13/pflag" -) - -// Seconds provides convenience functions for extracting -// duration from float64 seconds values. -type Seconds float64 - -// SecondsVar is like a flag.Float64Var, but it works for Seconds. -func SecondsVar(fs *pflag.FlagSet, p *Seconds, name string, value Seconds, usage string) { - fs.Float64Var((*float64)(p), name, float64(value), usage) -} - -// Get converts Seconds to time.Duration -func (s Seconds) Get() time.Duration { - return time.Duration(s * Seconds(1*time.Second)) -} - -// Set sets the value from time.Duration -func (s *Seconds) Set(d time.Duration) { - *s = Seconds(d) / Seconds(1*time.Second) -} diff --git a/go/vt/vttablet/tabletserver/tabletenv/seconds_test.go b/go/vt/vttablet/tabletserver/tabletenv/seconds_test.go deleted file mode 100644 index dc09a3f419f..00000000000 --- a/go/vt/vttablet/tabletserver/tabletenv/seconds_test.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2020 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 tabletenv - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/yaml2" -) - -func TestSecondsYaml(t *testing.T) { - type testSecond struct { - Value Seconds `json:"value"` - } - - ts := testSecond{ - Value: 1, - } - gotBytes, err := yaml2.Marshal(&ts) - require.NoError(t, err) - wantBytes := "value: 1\n" - assert.Equal(t, wantBytes, string(gotBytes)) - - var gotts testSecond - err = yaml2.Unmarshal([]byte(wantBytes), &gotts) - require.NoError(t, err) - assert.Equal(t, ts, gotts) -} - -func TestSecondsGetSet(t *testing.T) { - var val Seconds - val.Set(2 * time.Second) - assert.Equal(t, Seconds(2), val) - assert.Equal(t, 2*time.Second, val.Get()) -} diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index ac52a92a9f4..27510be5824 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -37,6 +37,7 @@ import ( "vitess.io/vitess/go/pools/smartconnpool" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/stats" + "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/tb" "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/callerid" @@ -189,23 +190,24 @@ func NewTabletServer(ctx context.Context, env *vtenv.Environment, name string, c tsv.onlineDDLExecutor = onlineddl.NewExecutor(tsv, alias, topoServer, tsv.lagThrottler, tabletTypeFunc, tsv.onlineDDLExecutorToggleTableBuffer, tsv.tableGC.RequestChecks, tsv.te.preparedPool.IsEmptyForTable) tsv.sm = &stateManager{ - statelessql: tsv.statelessql, - statefulql: tsv.statefulql, - olapql: tsv.olapql, - hs: tsv.hs, - se: tsv.se, - rt: tsv.rt, - vstreamer: tsv.vstreamer, - tracker: tsv.tracker, - watcher: tsv.watcher, - qe: tsv.qe, - txThrottler: tsv.txThrottler, - te: tsv.te, - messager: tsv.messager, - ddle: tsv.onlineDDLExecutor, - throttler: tsv.lagThrottler, - tableGC: tsv.tableGC, - rw: newRequestsWaiter(), + statelessql: tsv.statelessql, + statefulql: tsv.statefulql, + olapql: tsv.olapql, + hs: tsv.hs, + se: tsv.se, + rt: tsv.rt, + vstreamer: tsv.vstreamer, + tracker: tsv.tracker, + watcher: tsv.watcher, + qe: tsv.qe, + txThrottler: tsv.txThrottler, + te: tsv.te, + messager: tsv.messager, + ddle: tsv.onlineDDLExecutor, + throttler: tsv.lagThrottler, + tableGC: tsv.tableGC, + rw: newRequestsWaiter(), + diskHealthMonitor: newDiskHealthMonitor(ctx), } tsv.exporter.NewGaugeFunc("TabletState", "Tablet server state", func() int64 { return int64(tsv.sm.State()) }) @@ -758,6 +760,19 @@ func (tsv *TabletServer) WaitForPreparedTwoPCTransactions(ctx context.Context) e } } +// SetDemotePrimaryStalled marks that demote primary is stalled in the state manager. +func (tsv *TabletServer) SetDemotePrimaryStalled() { + tsv.sm.mu.Lock() + tsv.sm.demotePrimaryStalled = true + tsv.sm.mu.Unlock() + tsv.BroadcastHealth() +} + +// IsDiskStalled returns if the disk is stalled or not. +func (tsv *TabletServer) IsDiskStalled() bool { + return tsv.sm.diskHealthMonitor.IsDiskStalled() +} + // CreateTransaction creates the metadata for a 2PC transaction. func (tsv *TabletServer) CreateTransaction(ctx context.Context, target *querypb.Target, dtid string, participants []*querypb.Target) (err error) { return tsv.execRequest( @@ -1543,7 +1558,7 @@ func (tsv *TabletServer) execRequest( defer span.Finish() - logStats := tabletenv.NewLogStats(ctx, requestName) + logStats := tabletenv.NewLogStats(ctx, requestName, streamlog.GetQueryLogConfig()) logStats.Target = target logStats.OriginalSQL = sql logStats.BindVariables = sqltypes.CopyBindVariables(bindVariables) @@ -1867,7 +1882,9 @@ func (tsv *TabletServer) registerQuerylogzHandler() { } func (tsv *TabletServer) registerTxlogzHandler() { - tsv.exporter.HandleFunc("/txlogz", txlogzHandler) + tsv.exporter.HandleFunc("/txlogz", func(w http.ResponseWriter, r *http.Request) { + txlogzHandler(w, r, streamlog.GetQueryLogConfig().RedactDebugUIQueries) + }) } func (tsv *TabletServer) registerQueryListHandlers(queryLists []*QueryList) { @@ -1882,7 +1899,7 @@ func (tsv *TabletServer) registerQueryListHandlers(queryLists []*QueryList) { func (tsv *TabletServer) registerTwopczHandler() { tsv.exporter.HandleFunc("/twopcz", func(w http.ResponseWriter, r *http.Request) { ctx := tabletenv.LocalContext() - txe := NewDTExecutor(ctx, tabletenv.NewLogStats(ctx, "twopcz"), tsv.te, tsv.qe, tsv.getShard) + txe := NewDTExecutor(ctx, tabletenv.NewLogStats(ctx, "twopcz", streamlog.GetQueryLogConfig()), tsv.te, tsv.qe, tsv.getShard) twopczHandler(txe, w, r) }) } diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index 621941224a9..e4faf4ee6c9 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -33,6 +33,7 @@ import ( "vitess.io/vitess/go/mysql/config" "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/stats" + "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/callerid" "vitess.io/vitess/go/vt/sidecardb" "vitess.io/vitess/go/vt/vtenv" @@ -1659,7 +1660,7 @@ func TestPurgeMessages(t *testing.T) { func TestHandleExecUnknownError(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - logStats := tabletenv.NewLogStats(ctx, "TestHandleExecError") + logStats := tabletenv.NewLogStats(ctx, "TestHandleExecError", streamlog.NewQueryLogConfigForTest()) cfg := tabletenv.NewDefaultConfig() srvTopoCounts := stats.NewCountersWithSingleLabel("", "Resilient srvtopo server operations", "type") tsv := NewTabletServer(ctx, vtenv.NewTestEnv(), "TabletServerTest", cfg, memorytopo.NewServer(ctx, ""), &topodatapb.TabletAlias{}, srvTopoCounts) @@ -1676,7 +1677,7 @@ func TestHandlePanicAndSendLogStatsMessageTruncation(t *testing.T) { defer cancel() tl := newTestLogger() defer tl.Close() - logStats := tabletenv.NewLogStats(ctx, "TestHandlePanicAndSendLogStatsMessageTruncation") + logStats := tabletenv.NewLogStats(ctx, "TestHandlePanicAndSendLogStatsMessageTruncation", streamlog.NewQueryLogConfigForTest()) env, err := vtenv.New(vtenv.Options{ MySQLServerVersion: config.DefaultMySQLVersion, TruncateErrLen: 32, diff --git a/go/vt/vttablet/tabletserver/tx_engine.go b/go/vt/vttablet/tabletserver/tx_engine.go index b6e0e69b86d..d0ca4ec498c 100644 --- a/go/vt/vttablet/tabletserver/tx_engine.go +++ b/go/vt/vttablet/tabletserver/tx_engine.go @@ -116,20 +116,19 @@ func NewTxEngine(env tabletenv.Env, dxNotifier func()) *TxEngine { te.txPool = NewTxPool(env, limiter) // We initially allow twoPC (handles vttablet restarts). // We will disallow them for a few reasons - - // 1. when a new tablet is promoted if semi-sync is turned off. + // 1. When a new tablet is promoted if semi-sync is turned off. // 2. TabletControls have been set by a Resharding workflow. te.twopcAllowed = make([]bool, TwoPCAllowed_Len) for idx := range te.twopcAllowed { te.twopcAllowed[idx] = true } - te.twopcEnabled = config.TwoPCEnable - if te.twopcEnabled { - if config.TwoPCAbandonAge <= 0 { - log.Error("2PC abandon age not specified: Disabling 2PC") - te.twopcEnabled = false - } + te.twopcEnabled = true + if config.TwoPCAbandonAge <= 0 { + log.Error("2PC abandon age not specified: Disabling 2PC") + te.twopcEnabled = false } - te.abandonAge = config.TwoPCAbandonAge.Get() + + te.abandonAge = config.TwoPCAbandonAge te.ticks = timer.NewTimer(te.abandonAge / 2) // Set the prepared pool capacity to something lower than diff --git a/go/vt/vttablet/tabletserver/tx_engine_test.go b/go/vt/vttablet/tabletserver/tx_engine_test.go index f4dd0596691..cba7bf86e8f 100644 --- a/go/vt/vttablet/tabletserver/tx_engine_test.go +++ b/go/vt/vttablet/tabletserver/tx_engine_test.go @@ -613,8 +613,7 @@ func TestCheckReceivedError(t *testing.T) { cfg := tabletenv.NewDefaultConfig() cfg.DB = newDBConfigs(db) env := tabletenv.NewEnv(vtenv.NewTestEnv(), cfg, "TabletServerTest") - env.Config().TwoPCEnable = true - env.Config().TwoPCAbandonAge = 5 + env.Config().TwoPCAbandonAge = 5 * time.Second te := NewTxEngine(env, nil) te.AcceptReadWrite() @@ -791,8 +790,7 @@ func TestPrepareTx(t *testing.T) { db.AddRejectedQuery("retryable query", sqlerror.NewSQLError(sqlerror.CRConnectionError, "", "Retryable error")) cfg := tabletenv.NewDefaultConfig() cfg.DB = newDBConfigs(db) - cfg.TwoPCEnable = true - cfg.TwoPCAbandonAge = 200 + cfg.TwoPCAbandonAge = 200 * time.Second te := NewTxEngine(tabletenv.NewEnv(vtenv.NewTestEnv(), cfg, "TabletServerTest"), nil) te.AcceptReadWrite() db.ResetQueryLog() diff --git a/go/vt/vttablet/tabletserver/txlogz.go b/go/vt/vttablet/tabletserver/txlogz.go index 8d1b88c8c85..9a60812ca0b 100644 --- a/go/vt/vttablet/tabletserver/txlogz.go +++ b/go/vt/vttablet/tabletserver/txlogz.go @@ -25,7 +25,6 @@ import ( "github.com/google/safehtml/template" "vitess.io/vitess/go/acl" - "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/callerid" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logz" @@ -76,13 +75,13 @@ var ( // Endpoint: /txlogz?timeout=%d&limit=%d // timeout: the txlogz will keep dumping transactions until timeout // limit: txlogz will keep dumping transactions until it hits the limit -func txlogzHandler(w http.ResponseWriter, req *http.Request) { +func txlogzHandler(w http.ResponseWriter, req *http.Request, redactUIQuery bool) { if err := acl.CheckAccessHTTP(req, acl.DEBUGGING); err != nil { acl.SendError(w, err) return } - if streamlog.GetRedactDebugUIQueries() { + if redactUIQuery { io.WriteString(w, ` diff --git a/go/vt/vttablet/tabletserver/txlogz_test.go b/go/vt/vttablet/tabletserver/txlogz_test.go index 8faec74d07b..4556665a52a 100644 --- a/go/vt/vttablet/tabletserver/txlogz_test.go +++ b/go/vt/vttablet/tabletserver/txlogz_test.go @@ -27,8 +27,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/tx" "vitess.io/vitess/go/vt/callerid" - - "vitess.io/vitess/go/streamlog" ) func testNotRedacted(t *testing.T, r *httptest.ResponseRecorder) { @@ -45,11 +43,10 @@ func testRedacted(t *testing.T, r *httptest.ResponseRecorder) { func testHandler(req *http.Request, t *testing.T) { // Test with redactions off to start - streamlog.SetRedactDebugUIQueries(false) response := httptest.NewRecorder() tabletenv.TxLogger.Send("test msg") - txlogzHandler(response, req) + txlogzHandler(response, req, false) if !strings.Contains(response.Body.String(), "error") { t.Fatalf("should show an error page since transaction log format is invalid.") } @@ -66,26 +63,22 @@ func testHandler(req *http.Request, t *testing.T) { txConn.txProps.EndTime = txConn.txProps.StartTime response = httptest.NewRecorder() tabletenv.TxLogger.Send(txConn) - txlogzHandler(response, req) + txlogzHandler(response, req, false) testNotRedacted(t, response) txConn.txProps.EndTime = txConn.txProps.StartTime.Add(time.Duration(2) * time.Second) response = httptest.NewRecorder() tabletenv.TxLogger.Send(txConn) - txlogzHandler(response, req) + txlogzHandler(response, req, false) testNotRedacted(t, response) txConn.txProps.EndTime = txConn.txProps.StartTime.Add(time.Duration(500) * time.Millisecond) response = httptest.NewRecorder() tabletenv.TxLogger.Send(txConn) - txlogzHandler(response, req) + txlogzHandler(response, req, false) testNotRedacted(t, response) // Test with redactions on - streamlog.SetRedactDebugUIQueries(true) - txlogzHandler(response, req) + txlogzHandler(response, req, true) testRedacted(t, response) - - // Reset to default redaction state - streamlog.SetRedactDebugUIQueries(false) } func TestTxlogzHandler(t *testing.T) { diff --git a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go index 10428ed67c7..d8962f1c2b8 100644 --- a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go +++ b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go @@ -19,14 +19,13 @@ limitations under the License. package txserializer import ( + "context" "fmt" "net/http" "strings" "sync" "time" - "context" - "vitess.io/vitess/go/acl" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/streamlog" @@ -87,9 +86,10 @@ type TxSerializer struct { logQueueExceededDryRun *logutil.ThrottledLogger logGlobalQueueExceededDryRun *logutil.ThrottledLogger - mu sync.Mutex - queues map[string]*queue - globalSize int + mu sync.Mutex + queues map[string]*queue + globalSize int + redactUIQuery bool } // New returns a TxSerializer object. @@ -130,6 +130,7 @@ func New(env tabletenv.Env) *TxSerializer { logQueueExceededDryRun: logutil.NewThrottledLogger("HotRowProtection QueueExceeded DryRun", 5*time.Second), logGlobalQueueExceededDryRun: logutil.NewThrottledLogger("HotRowProtection GlobalQueueExceeded DryRun", 5*time.Second), queues: make(map[string]*queue), + redactUIQuery: streamlog.NewQueryLogConfigForTest().RedactDebugUIQueries, } } @@ -328,7 +329,7 @@ func (txs *TxSerializer) Pending(key string) int { // ServeHTTP lists the most recent, cached queries and their count. func (txs *TxSerializer) ServeHTTP(response http.ResponseWriter, request *http.Request) { - if streamlog.GetRedactDebugUIQueries() { + if txs.redactUIQuery { response.Write([]byte(` diff --git a/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go b/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go index e1b4b5a7612..d53c434d9b6 100644 --- a/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go +++ b/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go @@ -26,7 +26,6 @@ import ( "testing" "time" - "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" @@ -71,17 +70,13 @@ func TestTxSerializer_NoHotRow(t *testing.T) { } func TestTxSerializerRedactDebugUI(t *testing.T) { - streamlog.SetRedactDebugUIQueries(true) - defer func() { - streamlog.SetRedactDebugUIQueries(false) - }() - cfg := tabletenv.NewDefaultConfig() cfg.HotRowProtection.MaxQueueSize = 1 cfg.HotRowProtection.MaxGlobalQueueSize = 1 cfg.HotRowProtection.MaxConcurrency = 5 txs := New(tabletenv.NewEnv(vtenv.NewTestEnv(), cfg, "TxSerializerTest")) resetVariables(txs) + txs.redactUIQuery = true done, waited, err := txs.Wait(context.Background(), "t1 where1", "t1") if err != nil { diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index 31c47674233..317936e4289 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -276,7 +276,8 @@ func (rs *rowStreamer) buildSelect(st *binlogdatapb.MinimalTable) (string, error buf.Myprintf(" from %v%s", sqlparser.NewIdentifierCS(rs.plan.Table.Name), indexHint) if len(rs.lastpk) != 0 { if len(rs.lastpk) != len(rs.pkColumns) { - return "", fmt.Errorf("primary key values don't match length: %v vs %v", rs.lastpk, rs.pkColumns) + return "", fmt.Errorf("cannot build a row streamer plan for the %s table as a lastpk value was provided and the number of primary key values within it (%v) does not match the number of primary key columns in the table (%d)", + st.Name, rs.lastpk, rs.pkColumns) } buf.WriteString(" where ") prefix := "" diff --git a/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go index 632579551c0..552a713b145 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go +++ b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go @@ -205,7 +205,11 @@ func (te *Env) SetVSchema(vs string) error { if err := json2.UnmarshalPB([]byte(vs), &kspb); err != nil { return err } - if err := te.TopoServ.SaveVSchema(ctx, te.KeyspaceName, &kspb); err != nil { + ksvs := &topo.KeyspaceVSchemaInfo{ + Name: te.KeyspaceName, + Keyspace: &kspb, + } + if err := te.TopoServ.SaveVSchema(ctx, ksvs); err != nil { return err } te.SchemaEngine.Reload(ctx) diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 59db723ff2b..fb4cb324047 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -623,7 +623,7 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent, bufferAndTransmit func(vev if vevent != nil { vevents = append(vevents, vevent) } - case ev.IsWriteRows() || ev.IsDeleteRows() || ev.IsUpdateRows(): + case ev.IsWriteRows() || ev.IsDeleteRows() || ev.IsUpdateRows() || ev.IsPartialUpdateRows(): // The existence of before and after images can be used to // identify statement types. It's also possible that the // before and after images end up going to different shards. @@ -973,7 +973,7 @@ func (vs *vstreamer) processJournalEvent(vevents []*binlogdatapb.VEvent, plan *s } nextrow: for _, row := range rows.Rows { - afterOK, afterValues, _, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns) + afterOK, afterValues, _, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns, row.JSONPartialValues) if err != nil { return nil, err } @@ -1011,11 +1011,14 @@ nextrow: func (vs *vstreamer) processRowEvent(vevents []*binlogdatapb.VEvent, plan *streamerPlan, rows mysql.Rows) ([]*binlogdatapb.VEvent, error) { rowChanges := make([]*binlogdatapb.RowChange, 0, len(rows.Rows)) for _, row := range rows.Rows { - beforeOK, beforeValues, _, err := vs.extractRowAndFilter(plan, row.Identify, rows.IdentifyColumns, row.NullIdentifyColumns) + // The BEFORE image does not have partial JSON values so we pass an empty bitmap. + beforeOK, beforeValues, _, err := vs.extractRowAndFilter(plan, row.Identify, rows.IdentifyColumns, row.NullIdentifyColumns, mysql.Bitmap{}) if err != nil { return nil, err } - afterOK, afterValues, partial, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns) + // The AFTER image is where we may have partial JSON values, as reflected in the + // row's JSONPartialValues bitmap. + afterOK, afterValues, partial, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns, row.JSONPartialValues) if err != nil { return nil, err } @@ -1028,14 +1031,20 @@ func (vs *vstreamer) processRowEvent(vevents []*binlogdatapb.VEvent, plan *strea } if afterOK { rowChange.After = sqltypes.RowToProto3(afterValues) - if (vs.config.ExperimentalFlags /**/ & /**/ vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage != 0) && - partial { + if ((vs.config.ExperimentalFlags /**/ & /**/ vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage != 0) && partial) || + (row.JSONPartialValues.Count() > 0) { rowChange.DataColumns = &binlogdatapb.RowChange_Bitmap{ Count: int64(rows.DataColumns.Count()), Cols: rows.DataColumns.Bits(), } } + if row.JSONPartialValues.Count() > 0 { + rowChange.JsonPartialValues = &binlogdatapb.RowChange_Bitmap{ + Count: int64(row.JSONPartialValues.Count()), + Cols: row.JSONPartialValues.Bits(), + } + } } rowChanges = append(rowChanges, rowChange) } @@ -1081,13 +1090,14 @@ func (vs *vstreamer) rebuildPlans() error { // - true, if row needs to be skipped because of workflow filter rules // - data values, array of one value per column // - true, if the row image was partial (i.e. binlog_row_image=noblob and dml doesn't update one or more blob/text columns) -func (vs *vstreamer) extractRowAndFilter(plan *streamerPlan, data []byte, dataColumns, nullColumns mysql.Bitmap) (bool, []sqltypes.Value, bool, error) { +func (vs *vstreamer) extractRowAndFilter(plan *streamerPlan, data []byte, dataColumns, nullColumns mysql.Bitmap, jsonPartialValues mysql.Bitmap) (bool, []sqltypes.Value, bool, error) { if len(data) == 0 { return false, nil, false, nil } values := make([]sqltypes.Value, dataColumns.Count()) charsets := make([]collations.ID, len(values)) valueIndex := 0 + jsonIndex := 0 pos := 0 partial := false for colNum := 0; colNum < dataColumns.Count(); colNum++ { @@ -1101,9 +1111,17 @@ func (vs *vstreamer) extractRowAndFilter(plan *streamerPlan, data []byte, dataCo } if nullColumns.Bit(valueIndex) { valueIndex++ + if plan.Table.Fields[colNum].Type == querypb.Type_JSON { + jsonIndex++ + } continue } - value, l, err := mysqlbinlog.CellValue(data, pos, plan.TableMap.Types[colNum], plan.TableMap.Metadata[colNum], plan.Table.Fields[colNum]) + partialJSON := false + if jsonPartialValues.Count() > 0 && plan.Table.Fields[colNum].Type == querypb.Type_JSON { + partialJSON = jsonPartialValues.Bit(jsonIndex) + jsonIndex++ + } + value, l, err := mysqlbinlog.CellValue(data, pos, plan.TableMap.Types[colNum], plan.TableMap.Metadata[colNum], plan.Table.Fields[colNum], partialJSON) if err != nil { log.Errorf("extractRowAndFilter: %s, table: %s, colNum: %d, fields: %+v, current values: %+v", err, plan.Table.Name, colNum, plan.Table.Fields, values) diff --git a/go/vt/vttablet/tabletservermock/controller.go b/go/vt/vttablet/tabletservermock/controller.go index 9d570b8f6c7..21b38755302 100644 --- a/go/vt/vttablet/tabletservermock/controller.go +++ b/go/vt/vttablet/tabletservermock/controller.go @@ -274,6 +274,17 @@ func (tqsc *Controller) WaitForPreparedTwoPCTransactions(context.Context) error return nil } +// SetDemotePrimaryStalled is part of the tabletserver.Controller interface +func (tqsc *Controller) SetDemotePrimaryStalled() { + tqsc.MethodCalled["SetDemotePrimaryStalled"] = true +} + +// IsDiskStalled is part of the tabletserver.Controller interface +func (tqsc *Controller) IsDiskStalled() bool { + tqsc.MethodCalled["IsDiskStalled"] = true + return false +} + // EnterLameduck implements tabletserver.Controller. func (tqsc *Controller) EnterLameduck() { tqsc.mu.Lock() diff --git a/go/vt/vttest/vtprocess.go b/go/vt/vttest/vtprocess.go index 6371811a60e..1719fafd8a7 100644 --- a/go/vt/vttest/vtprocess.go +++ b/go/vt/vttest/vtprocess.go @@ -205,7 +205,7 @@ func VtcomboProcess(environment Environment, args *Config, mysql MySQLManager) ( if args.VtComboBindAddress != "" { vtcomboBindAddress = args.VtComboBindAddress } - grpcBindAddress := "127.0.0.1" + grpcBindAddress := "" if servenv.GRPCBindAddress() != "" { grpcBindAddress = servenv.GRPCBindAddress() } diff --git a/go/vt/wrangler/materializer.go b/go/vt/wrangler/materializer.go index 7e24945cde7..27aaa6935be 100644 --- a/go/vt/wrangler/materializer.go +++ b/go/vt/wrangler/materializer.go @@ -148,8 +148,10 @@ func (wr *Wrangler) MoveTables(ctx context.Context, workflow, sourceKeyspace, ta log.Infof("Successfully opened external topo: %+v", externalTopo) } - var vschema *vschemapb.Keyspace - var origVSchema *vschemapb.Keyspace // If we need to rollback a failed create + var ( + vschema *topo.KeyspaceVSchemaInfo + origVSchema *topo.KeyspaceVSchemaInfo // If we need to rollback a failed create + ) vschema, err = wr.ts.GetVSchema(ctx, targetKeyspace) if err != nil { return err @@ -215,7 +217,7 @@ func (wr *Wrangler) MoveTables(ctx context.Context, workflow, sourceKeyspace, ta // Save the original in case we need to restore it for a late failure // in the defer(). origVSchema = vschema.CloneVT() - if err := wr.addTablesToVSchema(ctx, sourceKeyspace, vschema, tables, externalTopo == nil); err != nil { + if err := wr.addTablesToVSchema(ctx, sourceKeyspace, vschema.Keyspace, tables, externalTopo == nil); err != nil { return err } } @@ -280,7 +282,7 @@ func (wr *Wrangler) MoveTables(ctx context.Context, workflow, sourceKeyspace, ta if origVSchema == nil { // There's no previous version to restore return } - if cerr := wr.ts.SaveVSchema(ctx, targetKeyspace, origVSchema); cerr != nil { + if cerr := wr.ts.SaveVSchema(ctx, origVSchema); cerr != nil { err = vterrors.Wrapf(err, "failed to restore original target vschema: %v", cerr) } } @@ -321,7 +323,7 @@ func (wr *Wrangler) MoveTables(ctx context.Context, workflow, sourceKeyspace, ta } // We added to the vschema. - if err := wr.ts.SaveVSchema(ctx, targetKeyspace, vschema); err != nil { + if err := wr.ts.SaveVSchema(ctx, vschema); err != nil { return err } } @@ -477,7 +479,7 @@ func (wr *Wrangler) CreateLookupVindex(ctx context.Context, keyspace string, spe if err != nil { return err } - if err := wr.ts.SaveVSchema(ctx, ms.TargetKeyspace, targetVSchema); err != nil { + if err := wr.ts.SaveVSchema(ctx, targetVSchema); err != nil { return err } ms.Cell = cell @@ -495,7 +497,7 @@ func (wr *Wrangler) CreateLookupVindex(ctx context.Context, keyspace string, spe if err := wr.Materialize(ctx, ms); err != nil { return err } - if err := wr.ts.SaveVSchema(ctx, keyspace, sourceVSchema); err != nil { + if err := wr.ts.SaveVSchema(ctx, sourceVSchema); err != nil { return err } @@ -503,7 +505,7 @@ func (wr *Wrangler) CreateLookupVindex(ctx context.Context, keyspace string, spe } // prepareCreateLookup performs the preparatory steps for creating a lookup vindex. -func (wr *Wrangler) prepareCreateLookup(ctx context.Context, keyspace string, specs *vschemapb.Keyspace, continueAfterCopyWithOwner bool) (ms *vtctldatapb.MaterializeSettings, sourceVSchema, targetVSchema *vschemapb.Keyspace, err error) { +func (wr *Wrangler) prepareCreateLookup(ctx context.Context, keyspace string, specs *vschemapb.Keyspace, continueAfterCopyWithOwner bool) (ms *vtctldatapb.MaterializeSettings, sourceVSchema, targetVSchema *topo.KeyspaceVSchemaInfo, err error) { // Important variables are pulled out here. var ( // lookup vindex info @@ -551,11 +553,8 @@ func (wr *Wrangler) prepareCreateLookup(ctx context.Context, keyspace string, sp if len(vindexFromCols) != 1 { return nil, nil, nil, fmt.Errorf("unique vindex 'from' should have only one column: %v", vindex) } - } else { - if len(vindexFromCols) < 2 { - return nil, nil, nil, fmt.Errorf("non-unique vindex 'from' should have more than one column: %v", vindex) - } } + vindexToCol = vindex.Params["to"] // Make the vindex write_only. If one exists already in the vschema, // it will need to match this vindex exactly, including the write_only setting. @@ -931,7 +930,7 @@ func (wr *Wrangler) ExternalizeVindex(ctx context.Context, qualifiedVindexName s // Remove the write_only param and save the source vschema. delete(sourceVindex.Params, "write_only") - if err := wr.ts.SaveVSchema(ctx, sourceKeyspace, sourceVSchema); err != nil { + if err := wr.ts.SaveVSchema(ctx, sourceVSchema); err != nil { return err } return wr.ts.RebuildSrvVSchema(ctx, nil) @@ -1065,7 +1064,7 @@ func (wr *Wrangler) buildMaterializer(ctx context.Context, ms *vtctldatapb.Mater if err != nil { return nil, err } - targetVSchema, err := vindexes.BuildKeyspaceSchema(vschema, ms.TargetKeyspace, wr.env.Parser()) + targetVSchema, err := vindexes.BuildKeyspaceSchema(vschema.Keyspace, ms.TargetKeyspace, wr.env.Parser()) if err != nil { return nil, err } @@ -1132,7 +1131,7 @@ func (wr *Wrangler) buildMaterializer(ctx context.Context, ms *vtctldatapb.Mater if err != nil { return nil, fmt.Errorf("failed to get source keyspace vschema: %v", err) } - differentPVs = primaryVindexesDiffer(ms, sourceVSchema, vschema) + differentPVs = primaryVindexesDiffer(ms, sourceVSchema.Keyspace, vschema.Keyspace) return &materializer{ wr: wr, diff --git a/go/vt/wrangler/materializer_test.go b/go/vt/wrangler/materializer_test.go index 1728ba6efc2..a406516446f 100644 --- a/go/vt/wrangler/materializer_test.go +++ b/go/vt/wrangler/materializer_test.go @@ -34,6 +34,7 @@ import ( "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/sqlparser" + "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" @@ -329,10 +330,16 @@ func TestCreateLookupVindexFull(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.TargetKeyspace, &vschemapb.Keyspace{}); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: &vschemapb.Keyspace{}, + }); err != nil { t.Fatal(err) } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, sourceVSchema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: sourceVSchema, + }); err != nil { t.Fatal(err) } @@ -376,7 +383,7 @@ func TestCreateLookupVindexFull(t *testing.T) { } vschema, err := env.topoServ.GetVSchema(ctx, ms.SourceKeyspace) require.NoError(t, err) - utils.MustMatch(t, wantvschema, vschema) + utils.MustMatch(t, wantvschema, vschema.Keyspace) wantvschema = &vschemapb.Keyspace{ Tables: map[string]*vschemapb.Table{ @@ -385,7 +392,7 @@ func TestCreateLookupVindexFull(t *testing.T) { } vschema, err = env.topoServ.GetVSchema(ctx, ms.TargetKeyspace) require.NoError(t, err) - utils.MustMatch(t, wantvschema, vschema) + utils.MustMatch(t, wantvschema, vschema.Keyspace) } func TestCreateLookupVindexCreateDDL(t *testing.T) { @@ -412,7 +419,10 @@ func TestCreateLookupVindexCreateDDL(t *testing.T) { }, }, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -827,10 +837,16 @@ func TestCreateLookupVindexSourceVSchema(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.TargetKeyspace, &vschemapb.Keyspace{}); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: &vschemapb.Keyspace{}, + }); err != nil { t.Fatal(err) } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, tcase.sourceVSchema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: tcase.sourceVSchema, + }); err != nil { t.Fatal(err) } @@ -866,7 +882,10 @@ func TestCreateLookupVindexTargetVSchema(t *testing.T) { }, }, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, sourcevs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: sourcevs, + }); err != nil { t.Fatal(err) } @@ -1063,7 +1082,10 @@ func TestCreateLookupVindexTargetVSchema(t *testing.T) { }}, } specs.Vindexes["v"].Params["table"] = fmt.Sprintf("%s.%s", ms.TargetKeyspace, tcase.targetTable) - if err := env.topoServ.SaveVSchema(context.Background(), ms.TargetKeyspace, tcase.targetVSchema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: tcase.targetVSchema, + }); err != nil { t.Fatal(err) } @@ -1075,7 +1097,7 @@ func TestCreateLookupVindexTargetVSchema(t *testing.T) { continue } require.NoError(t, err) - utils.MustMatch(t, tcase.out, got, tcase.description) + utils.MustMatch(t, tcase.out, got.Keyspace, tcase.description) } } @@ -1178,7 +1200,10 @@ func TestCreateLookupVindexSameKeyspace(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } @@ -1287,7 +1312,10 @@ func TestCreateCustomizedVindex(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } @@ -1402,7 +1430,10 @@ func TestCreateLookupVindexIgnoreNulls(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } @@ -1480,7 +1511,10 @@ func TestStopAfterCopyFlag(t *testing.T) { Schema: sourceSchema, }}, } - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, vschema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: vschema, + }); err != nil { t.Fatal(err) } @@ -1536,10 +1570,16 @@ func TestCreateLookupVindexFailures(t *testing.T) { }, }, } - if err := topoServ.SaveVSchema(context.Background(), "sourceks", vs); err != nil { + if err := topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "sourceks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } - if err := topoServ.SaveVSchema(context.Background(), "targetks", &vschemapb.Keyspace{}); err != nil { + if err := topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: &vschemapb.Keyspace{}, + }); err != nil { t.Fatal(err) } @@ -1599,7 +1639,7 @@ func TestCreateLookupVindexFailures(t *testing.T) { }, err: "unique vindex 'from' should have only one column", }, { - description: "non-unique lookup should have more than one column", + description: "non-unique lookup can have only one column", input: &vschemapb.Keyspace{ Vindexes: map[string]*vschemapb.Vindex{ "v": { @@ -1612,7 +1652,7 @@ func TestCreateLookupVindexFailures(t *testing.T) { }, }, }, - err: "non-unique vindex 'from' should have more than one column", + err: "", }, { description: "vindex not found", input: &vschemapb.Keyspace{ @@ -1861,7 +1901,10 @@ func TestExternalizeVindex(t *testing.T) { }} for _, tcase := range testcases { // Resave the source schema for every iteration. - if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, sourceVSchema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: ms.SourceKeyspace, + Keyspace: sourceVSchema, + }); err != nil { t.Fatal(err) } if tcase.vrResponse != nil { @@ -2012,7 +2055,10 @@ func TestMaterializerOneToMany(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -2069,7 +2115,10 @@ func TestMaterializerManyToMany(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -2130,7 +2179,10 @@ func TestMaterializerMulticolumnVindex(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -2267,7 +2319,10 @@ func TestMaterializerExplicitColumns(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -2327,7 +2382,10 @@ func TestMaterializerRenamedColumns(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -2399,7 +2457,10 @@ func TestMaterializerNoTargetVSchema(t *testing.T) { Sharded: true, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } env.tmc.expectVRQuery(200, mzSelectFrozenQuery, &sqltypes.Result{}) @@ -2619,7 +2680,10 @@ func TestMaterializerNoGoodVindex(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -2660,7 +2724,10 @@ func TestMaterializerComplexVindexExpression(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -2701,7 +2768,10 @@ func TestMaterializerNoVindexInExpression(t *testing.T) { }, } - if err := env.topoServ.SaveVSchema(context.Background(), "targetks", vs); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -3138,11 +3208,17 @@ func TestMaterializerSourceShardSelection(t *testing.T) { for _, tcase := range testcases { t.Run(tcase.name, func(t *testing.T) { env, ctx := newTestMaterializerEnv(t, ms, tcase.sourceShards, tcase.targetShards) - if err := env.topoServ.SaveVSchema(ctx, "targetks", tcase.targetVSchema); err != nil { + if err := env.topoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "targetks", + Keyspace: tcase.targetVSchema, + }); err != nil { t.Fatal(err) } if tcase.sourceVSchema != nil { - if err := env.topoServ.SaveVSchema(context.Background(), "sourceks", tcase.sourceVSchema); err != nil { + if err := env.topoServ.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: "sourceks", + Keyspace: tcase.sourceVSchema, + }); err != nil { t.Fatal(err) } } @@ -3395,7 +3471,10 @@ func TestAddTablesToVSchema(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ts.SaveVSchema(ctx, srcks, tt.sourceVSchema) + ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: srcks, + Keyspace: tt.sourceVSchema, + }) err := wr.addTablesToVSchema(ctx, srcks, tt.inTargetVSchema, tt.tables, tt.copyVSchema) require.NoError(t, err) require.Equal(t, tt.wantTargetVSchema, tt.inTargetVSchema) @@ -3587,7 +3666,10 @@ func TestKeyRangesEqualOptimization(t *testing.T) { ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() // Target is always sharded. - err := env.wr.ts.SaveVSchema(ctx, targetKs, targetVSchema) + err := env.wr.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: targetKs, + Keyspace: targetVSchema, + }) require.NoError(t, err, "SaveVSchema failed: %v", err) for _, tablet := range env.tablets { diff --git a/go/vt/wrangler/reparent.go b/go/vt/wrangler/reparent.go index 1a3a45cf99b..e17f56de11f 100644 --- a/go/vt/wrangler/reparent.go +++ b/go/vt/wrangler/reparent.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/vt/topotools/events" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" @@ -131,7 +132,7 @@ func (wr *Wrangler) TabletExternallyReparented(ctx context.Context, newPrimaryAl return err } log.Infof("Getting a new durability policy for %v", durabilityName) - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return err } @@ -152,7 +153,7 @@ func (wr *Wrangler) TabletExternallyReparented(ctx context.Context, newPrimaryAl }() event.DispatchUpdate(ev, "starting external reparent") - if err := wr.tmc.ChangeType(ctx, tablet, topodatapb.TabletType_PRIMARY, reparentutil.SemiSyncAckers(durability, tablet) > 0); err != nil { + if err := wr.tmc.ChangeType(ctx, tablet, topodatapb.TabletType_PRIMARY, policy.SemiSyncAckers(durability, tablet) > 0); err != nil { log.Warningf("Error calling ChangeType on new primary %v: %v", topoproto.TabletAliasString(newPrimaryAlias), err) return err } diff --git a/go/vt/wrangler/resharder.go b/go/vt/wrangler/resharder.go index b041ce32041..09004032dd3 100644 --- a/go/vt/wrangler/resharder.go +++ b/go/vt/wrangler/resharder.go @@ -39,7 +39,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) type resharder struct { @@ -50,7 +49,7 @@ type resharder struct { sourcePrimaries map[string]*topo.TabletInfo targetShards []*topo.ShardInfo targetPrimaries map[string]*topo.TabletInfo - vschema *vschemapb.Keyspace + vschema *topo.KeyspaceVSchemaInfo refStreams map[string]*refStream cell string //single cell or cellsAlias or comma-separated list of cells/cellsAliases tabletTypes string diff --git a/go/vt/wrangler/resharder_test.go b/go/vt/wrangler/resharder_test.go index 4c47b3ebf14..2caa49c4f68 100644 --- a/go/vt/wrangler/resharder_test.go +++ b/go/vt/wrangler/resharder_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vtgate/vindexes" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -218,7 +219,10 @@ func TestResharderOneRefTable(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -272,7 +276,10 @@ func TestReshardStopFlags(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -325,7 +332,10 @@ func TestResharderOneRefStream(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -404,7 +414,10 @@ func TestResharderNoRefStream(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -627,7 +640,10 @@ func TestResharderUnnamedStream(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -677,7 +693,10 @@ func TestResharderMismatchedRefStreams(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -797,7 +816,10 @@ func TestResharderMixedTablesOrder1(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } @@ -866,7 +888,10 @@ func TestResharderMixedTablesOrder2(t *testing.T) { }, }, } - if err := env.wr.ts.SaveVSchema(context.Background(), env.keyspace, vs); err != nil { + if err := env.wr.ts.SaveVSchema(context.Background(), &topo.KeyspaceVSchemaInfo{ + Name: env.keyspace, + Keyspace: vs, + }); err != nil { t.Fatal(err) } diff --git a/go/vt/wrangler/tablet.go b/go/vt/wrangler/tablet.go index fdc6f9a92ac..31a5a7936ad 100644 --- a/go/vt/wrangler/tablet.go +++ b/go/vt/wrangler/tablet.go @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -141,12 +142,12 @@ func (wr *Wrangler) shouldSendSemiSyncAck(ctx context.Context, tablet *topodatap if err != nil { return false, err } - durability, err := reparentutil.GetDurabilityPolicy(durabilityName) + durability, err := policy.GetDurabilityPolicy(durabilityName) if err != nil { return false, err } - return reparentutil.IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet), nil + return policy.IsReplicaSemiSync(durability, shardPrimary.Tablet, tablet), nil } func (wr *Wrangler) getShardPrimaryForTablet(ctx context.Context, tablet *topodatapb.Tablet) (*topo.TabletInfo, error) { diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index cb61c4bab99..b540fc9f8f0 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -28,7 +28,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/mysql/capabilities" "vitess.io/vitess/go/mysql/fakesqldb" "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/sqltypes" @@ -36,6 +35,7 @@ import ( "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" + "vitess.io/vitess/go/vt/mysqlctl/blackbox" "vitess.io/vitess/go/vt/mysqlctl/filebackupstorage" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topo/topoproto" @@ -132,7 +132,7 @@ func testBackupRestore(t *testing.T, cDetails *compressionDetails) error { require.NoError(t, os.MkdirAll(s, os.ModePerm)) } - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := blackbox.NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { newPath := path.Join(sourceInnodbLogDir, mysql.DynamicRedoLogSubdir) @@ -371,7 +371,7 @@ func TestBackupRestoreLagged(t *testing.T) { } require.NoError(t, os.WriteFile(path.Join(sourceInnodbDataDir, "innodb_data_1"), []byte("innodb data 1 contents"), os.ModePerm)) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := blackbox.NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { newPath := path.Join(sourceInnodbLogDir, mysql.DynamicRedoLogSubdir) @@ -591,7 +591,7 @@ func TestRestoreUnreachablePrimary(t *testing.T) { } require.NoError(t, os.WriteFile(path.Join(sourceInnodbDataDir, "innodb_data_1"), []byte("innodb data 1 contents"), os.ModePerm)) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := blackbox.NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { newPath := path.Join(sourceInnodbLogDir, mysql.DynamicRedoLogSubdir) @@ -767,7 +767,7 @@ func TestDisableActiveReparents(t *testing.T) { } require.NoError(t, os.WriteFile(path.Join(sourceInnodbDataDir, "innodb_data_1"), []byte("innodb data 1 contents"), os.ModePerm)) - needIt, err := needInnoDBRedoLogSubdir() + needIt, err := blackbox.NeedInnoDBRedoLogSubdir() require.NoError(t, err) if needIt { newPath := path.Join(sourceInnodbLogDir, mysql.DynamicRedoLogSubdir) @@ -877,25 +877,3 @@ func TestDisableActiveReparents(t *testing.T) { assert.False(t, destTablet.FakeMysqlDaemon.Replicating) assert.True(t, destTablet.FakeMysqlDaemon.Running) } - -// needInnoDBRedoLogSubdir indicates whether we need to create a redo log subdirectory. -// Starting with MySQL 8.0.30, the InnoDB redo logs are stored in a subdirectory of the -// (/. by default) called "#innodb_redo". See: -// -// https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html#innodb-modifying-redo-log-capacity -func needInnoDBRedoLogSubdir() (needIt bool, err error) { - mysqldVersionStr, err := mysqlctl.GetVersionString() - if err != nil { - return needIt, err - } - _, sv, err := mysqlctl.ParseVersionString(mysqldVersionStr) - if err != nil { - return needIt, err - } - versionStr := fmt.Sprintf("%d.%d.%d", sv.Major, sv.Minor, sv.Patch) - capableOf := mysql.ServerVersionCapableOf(versionStr) - if capableOf == nil { - return needIt, fmt.Errorf("cannot determine database flavor details for version %s", versionStr) - } - return capableOf(capabilities.DynamicRedoLogCapacityFlavorCapability) -} diff --git a/go/vt/wrangler/testlib/emergency_reparent_shard_test.go b/go/vt/wrangler/testlib/emergency_reparent_shard_test.go index 3167be5e512..3251c7c8e3d 100644 --- a/go/vt/wrangler/testlib/emergency_reparent_shard_test.go +++ b/go/vt/wrangler/testlib/emergency_reparent_shard_test.go @@ -33,6 +33,7 @@ import ( "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtctl/reparentutil/reparenttestutil" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vttablet/tmclient" @@ -60,7 +61,7 @@ func TestEmergencyReparentShard(t *testing.T) { newPrimary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) goodReplica2 := NewFakeTablet(t, wr, "cell2", 3, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) oldPrimary.FakeMysqlDaemon.Replicating = false oldPrimary.FakeMysqlDaemon.SetPrimaryPositionLocked(replication.Position{ @@ -132,7 +133,8 @@ func TestEmergencyReparentShard(t *testing.T) { }, }, }) - goodReplica1RelayLogPos, _ := replication.ParseFilePosGTIDSet("relay-bin.000004:455") + goodReplica1RelayLogPos, err := replication.ParseFilePosGTIDSet("relay-bin.003222:18321744073709551612") // Requires all 64 bits or uint64 + require.NoError(t, err) goodReplica1.FakeMysqlDaemon.CurrentSourceFilePosition = replication.Position{ GTIDSet: goodReplica1RelayLogPos, } @@ -181,7 +183,7 @@ func TestEmergencyReparentShard(t *testing.T) { // run EmergencyReparentShard waitReplicaTimeout := time.Second * 2 - err := vp.Run([]string{"EmergencyReparentShard", "--wait_replicas_timeout", waitReplicaTimeout.String(), newPrimary.Tablet.Keyspace + "/" + newPrimary.Tablet.Shard, + err = vp.Run([]string{"EmergencyReparentShard", "--wait_replicas_timeout", waitReplicaTimeout.String(), newPrimary.Tablet.Keyspace + "/" + newPrimary.Tablet.Shard, topoproto.TabletAliasString(newPrimary.Tablet.Alias)}) require.NoError(t, err) // check what was run @@ -211,7 +213,7 @@ func TestEmergencyReparentShardPrimaryElectNotBest(t *testing.T) { oldPrimary := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) newPrimary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) moreAdvancedReplica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) // new primary newPrimary.FakeMysqlDaemon.Replicating = true diff --git a/go/vt/wrangler/testlib/planned_reparent_shard_test.go b/go/vt/wrangler/testlib/planned_reparent_shard_test.go index 1894c6bb4eb..f160ddfa32b 100644 --- a/go/vt/wrangler/testlib/planned_reparent_shard_test.go +++ b/go/vt/wrangler/testlib/planned_reparent_shard_test.go @@ -24,6 +24,7 @@ import ( "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtenv" "github.com/stretchr/testify/assert" @@ -60,7 +61,7 @@ func TestPlannedReparentShardNoPrimaryProvided(t *testing.T) { oldPrimary := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) newPrimary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) goodReplica1 := NewFakeTablet(t, wr, "cell2", 2, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) // new primary newPrimary.FakeMysqlDaemon.ReadOnly = true @@ -177,7 +178,7 @@ func TestPlannedReparentShardNoError(t *testing.T) { newPrimary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) goodReplica2 := NewFakeTablet(t, wr, "cell2", 3, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) // new primary newPrimary.FakeMysqlDaemon.ReadOnly = true @@ -312,7 +313,7 @@ func TestPlannedReparentInitialization(t *testing.T) { newPrimary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) goodReplica2 := NewFakeTablet(t, wr, "cell2", 3, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) // new primary newPrimary.FakeMysqlDaemon.ReadOnly = true @@ -691,7 +692,7 @@ func TestPlannedReparentShardRelayLogErrorStartReplication(t *testing.T) { // Create a primary, a couple good replicas primary := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) // old primary primary.FakeMysqlDaemon.ReadOnly = false diff --git a/go/vt/wrangler/testlib/reparent_utils_test.go b/go/vt/wrangler/testlib/reparent_utils_test.go index b199a64340a..7012822a017 100644 --- a/go/vt/wrangler/testlib/reparent_utils_test.go +++ b/go/vt/wrangler/testlib/reparent_utils_test.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/reparentutil" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtctl/reparentutil/reparenttestutil" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vttablet/tmclient" @@ -141,7 +142,7 @@ func TestReparentTablet(t *testing.T) { } primary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_PRIMARY, nil) replica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) // mark the primary inside the shard if _, err := ts.UpdateShardFields(ctx, "test_keyspace", "0", func(si *topo.ShardInfo) error { @@ -197,7 +198,7 @@ func TestSetReplicationSource(t *testing.T) { require.NoError(t, err, "CreateShard failed") primary := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_PRIMARY, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", "semi_sync") + reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) // mark the primary inside the shard _, err = ts.UpdateShardFields(ctx, "test_keyspace", "0", func(si *topo.ShardInfo) error { diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index d337c1ee515..9006e8b1555 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -995,7 +995,7 @@ func (wr *Wrangler) buildTrafficSwitcher(ctx context.Context, targetKeyspace, wo if err != nil { return nil, err } - ts.sourceKSSchema, err = vindexes.BuildKeyspaceSchema(vs, ts.sourceKeyspace, wr.env.Parser()) + ts.sourceKSSchema, err = vindexes.BuildKeyspaceSchema(vs.Keyspace, ts.sourceKeyspace, wr.env.Parser()) if err != nil { return nil, err } @@ -1833,7 +1833,7 @@ func (ts *trafficSwitcher) dropParticipatingTablesFromKeyspace(ctx context.Conte for _, tableName := range ts.Tables() { delete(vschema.Tables, tableName) } - return ts.TopoServer().SaveVSchema(ctx, keyspace, vschema) + return ts.TopoServer().SaveVSchema(ctx, vschema) } // FIXME: even after dropSourceShards there are still entries in the topo, need to research and fix @@ -1995,7 +1995,7 @@ func (ts *trafficSwitcher) addParticipatingTablesToKeyspace(ctx context.Context, vschema.Tables[table] = &vschemapb.Table{} } } - return ts.TopoServer().SaveVSchema(ctx, keyspace, vschema) + return ts.TopoServer().SaveVSchema(ctx, vschema) } func (ts *trafficSwitcher) isSequenceParticipating(ctx context.Context) (bool, error) { @@ -2034,7 +2034,7 @@ func (ts *trafficSwitcher) getTargetSequenceMetadata(ctx context.Context) (map[s return nil, nil } - sequencesByBackingTable, backingTablesFound, err := ts.findSequenceUsageInKeyspace(vschema) + sequencesByBackingTable, backingTablesFound, err := ts.findSequenceUsageInKeyspace(vschema.Keyspace) if err != nil { return nil, err } diff --git a/go/vt/wrangler/traffic_switcher_env_test.go b/go/vt/wrangler/traffic_switcher_env_test.go index a99e6ba2c43..0c7f705bb2d 100644 --- a/go/vt/wrangler/traffic_switcher_env_test.go +++ b/go/vt/wrangler/traffic_switcher_env_test.go @@ -206,12 +206,18 @@ func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, } tme.setPrimarySchemas(schema) if len(sourceShards) != 1 { - if err := tme.ts.SaveVSchema(ctx, "ks1", vs); err != nil { + if err := tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks1", + Keyspace: vs, + }); err != nil { t.Fatal(err) } } if len(targetShards) != 1 { - if err := tme.ts.SaveVSchema(ctx, "ks2", vs); err != nil { + if err := tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks2", + Keyspace: vs, + }); err != nil { t.Fatal(err) } } @@ -232,7 +238,10 @@ func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, tabletID += 10 gfdb := fakesqldb.New(t) tme.additionalPrimaries = append(tme.additionalPrimaries, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_PRIMARY, gfdb, TabletKeyspaceShard(t, "global", "0"))) - if err := tme.ts.SaveVSchema(ctx, "global", uvs); err != nil { + if err := tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "global", + Keyspace: uvs, + }); err != nil { t.Fatal(err) } @@ -246,7 +255,10 @@ func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, Column: "id", Sequence: "t2_seq", } - if err := tme.ts.SaveVSchema(ctx, "ks2", tks); err != nil { + if err := tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks2", + Keyspace: tks, + }); err != nil { t.Fatal(err) } @@ -459,9 +471,15 @@ func newTestTablePartialMigrater(ctx context.Context, t *testing.T, shards, shar }, }, } - err := tme.ts.SaveVSchema(ctx, "ks1", vs) + err := tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks1", + Keyspace: vs, + }) require.NoError(t, err) - err = tme.ts.SaveVSchema(ctx, "ks2", vs) + err = tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks2", + Keyspace: vs, + }) require.NoError(t, err) err = tme.ts.RebuildSrvVSchema(ctx, nil) require.NoError(t, err) @@ -630,7 +648,10 @@ func newTestShardMigrater(ctx context.Context, t *testing.T, sourceShards, targe }, }, } - if err := tme.ts.SaveVSchema(ctx, "ks", vs); err != nil { + if err := tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks", + Keyspace: vs, + }); err != nil { t.Fatal(err) } if err := tme.ts.RebuildSrvVSchema(ctx, nil); err != nil { diff --git a/go/vt/wrangler/traffic_switcher_test.go b/go/vt/wrangler/traffic_switcher_test.go index 5bc336f634e..4ee965ef96b 100644 --- a/go/vt/wrangler/traffic_switcher_test.go +++ b/go/vt/wrangler/traffic_switcher_test.go @@ -2170,8 +2170,11 @@ func TestNoOrphanedRoutingRulesOnFailedCreate(t *testing.T) { // fail. Let's also be sure that the routing rules are empty. err := topotools.SaveRoutingRules(ctx, tme.wr.ts, nil) require.NoError(t, err, "failed to save routing rules") - err = tme.ts.SaveVSchema(ctx, "ks2", &vschemapb.Keyspace{ - Sharded: true, + err = tme.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: "ks2", + Keyspace: &vschemapb.Keyspace{ + Sharded: true, + }, }) require.NoError(t, err, "failed to save vschema") err = tme.ts.RebuildSrvVSchema(ctx, nil) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 4caad42ce1f..2e9fc5f508d 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -167,6 +167,8 @@ type shardStreamer struct { err error } +var _ engine.StreamExecutor = (*shardStreamer)(nil) + // VDiff reports differences between the sources and targets of a vreplication workflow. func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflowName, sourceCell, targetCell, tabletTypesStr string, filteredReplicationWaitTime time.Duration, format string, maxRows int64, tables string, debug, onlyPks bool, @@ -1148,7 +1150,7 @@ func (pe *primitiveExecutor) drain(ctx context.Context) (int, error) { // ----------------------------------------------------------------- // shardStreamer -func (sm *shardStreamer) StreamExecute(ctx context.Context, vcursor engine.VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (sm *shardStreamer) StreamExecute(_ context.Context, _ engine.VCursor, _ map[string]*querypb.BindVariable, _, _ bool, callback func(*sqltypes.Result) error) error { for result := range sm.result { if err := callback(result); err != nil { return err diff --git a/java/example/pom.xml b/java/example/pom.xml index fa3220f51bd..19b5838510b 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -30,9 +30,9 @@ - mysql - mysql-connector-java - 8.0.28 + com.mysql + mysql-connector-j + 8.4.0 false diff --git a/java/example/src/main/java/io/vitess/example/MysqlJDBCExample.java b/java/example/src/main/java/io/vitess/example/MysqlJDBCExample.java index 05513eaa2bd..85717fb20f0 100644 --- a/java/example/src/main/java/io/vitess/example/MysqlJDBCExample.java +++ b/java/example/src/main/java/io/vitess/example/MysqlJDBCExample.java @@ -109,7 +109,7 @@ private static void readData(Connection conn) throws SQLException { } private static void validateReplica(Connection conn) throws SQLException { - String sql = "show slave status"; + String sql = "show replica status"; try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { if (!rs.next()) { throw new RuntimeException("connected to wrong tablet"); diff --git a/java/grpc-client/src/test/resources/ca.config b/java/grpc-client/src/test/resources/ca.config index e0955f28ccf..c5758831e06 100644 --- a/java/grpc-client/src/test/resources/ca.config +++ b/java/grpc-client/src/test/resources/ca.config @@ -2,6 +2,7 @@ default_bits = 1024 default_keyfile = keyfile.pem distinguished_name = req_distinguished_name + x509_extensions = v3_ca attributes = req_attributes prompt = no output_password = mypass @@ -15,3 +16,5 @@ emailAddress = test@email.address [ req_attributes ] challengePassword = A challenge password +[ v3_ca ] + basicConstraints = CA:TRUE diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index dd554e64501..a52048576a1 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -57,25 +57,6 @@ 3.12.4 test - - - org.powermock - powermock-api-mockito2 - 2.0.9 - test - - - org.powermock - powermock-core - 2.0.9 - test - - - org.powermock - powermock-module-junit4 - 2.0.9 - test - diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessJDBCUrl.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessJDBCUrl.java index e6a1b0187dd..3835ba543f8 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessJDBCUrl.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessJDBCUrl.java @@ -218,7 +218,7 @@ private static Properties getURLParamProperties(String paramString, Properties i } } - // Per the mysql-connector-java docs, passed in Properties values should take precedence + // Per the mysql-connector-j docs, passed in Properties values should take precedence // over // those in the URL. See javadoc for NonRegisteringDriver#connect if ((null != value && value.length() > 0) && (parameter.length() > 0) && null == info diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessMySQLDatabaseMetadata.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessMySQLDatabaseMetadata.java index 0235393a2c9..1f4e33585f3 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessMySQLDatabaseMetadata.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessMySQLDatabaseMetadata.java @@ -67,18 +67,19 @@ public class VitessMySQLDatabaseMetadata extends VitessDatabaseMetaData implemen "INNER", "INOUT", "INSENSITIVE", "INSERT", "INT", "INT1", "INT2", "INT3", "INT4", "INT8", "INTEGER", "INTERVAL", "INTO", "IS", "ITERATE", "JOIN", "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", "LIMIT", "LINEAR", "LINES", "LOAD", "LOCALTIME", "LOCALTIMESTAMP", - "LOCK", "LONG", "LONGBLOB", "LONGTEXT", "LOOP", "LOW_PRIORITY", "MATCH", "MEDIUMBLOB", - "MEDIUMINT", "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", "MINUTE_SECOND", "MOD", - "MODIFIES", "NATURAL", "NOT", "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE", - "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", "OUTFILE", "PRECISION", "PRIMARY", - "PROCEDURE", "PURGE", "RANGE", "READ", "READS", "READ_ONLY", "READ_WRITE", "REAL", - "REFERENCES", "REGEXP", "RELEASE", "RENAME", "REPEAT", "REPLACE", "REQUIRE", "RESTRICT", - "RETURN", "REVOKE", "RIGHT", "RLIKE", "SCHEMA", "SCHEMAS", "SECOND_MICROSECOND", "SELECT", - "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SMALLINT", "SPATIAL", "SPECIFIC", "SQL", - "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", - "SQL_SMALL_RESULT", "SSL", "STARTING", "STRAIGHT_JOIN", "TABLE", "TERMINATED", "THEN", - "TINYBLOB", "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRIGGER", "TRUE", "UNDO", "UNION", - "UNIQUE", "UNLOCK", "UNSIGNED", "UPDATE", "USAGE", "USE", "USING", "UTC_DATE", "UTC_TIME", + "LOCK", "LONG", "LONGBLOB", "LONGTEXT", "LOOP", "LOW_PRIORITY", "MANUAL", "MATCH", + "MEDIUMBLOB", "MEDIUMINT", "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", + "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", "NOT", "NO_WRITE_TO_BINLOG", "NULL", + "NUMERIC", "ON", "OPTIMIZE", "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", + "OUTFILE", "PARALLEL", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE", "QUALIFY", "RANGE", + "READ", "READS", "READ_ONLY", "READ_WRITE", "REAL", "REFERENCES", "REGEXP", "RELEASE", + "RENAME", "REPEAT", "REPLACE", "REQUIRE", "RESTRICT", "RETURN", "REVOKE", "RIGHT", + "RLIKE", "SCHEMA", "SCHEMAS", "SECOND_MICROSECOND", "SELECT", "SENSITIVE", "SEPARATOR", + "SET", "SHOW", "SMALLINT", "SPATIAL", "SPECIFIC", "SQL", "SQLEXCEPTION", "SQLSTATE", + "SQLWARNING", "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SSL", + "STARTING", "STRAIGHT_JOIN", "TABLE", "TABLESAMPLE", "TERMINATED", "THEN", "TINYBLOB", + "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRIGGER", "TRUE", "UNDO", "UNION", "UNIQUE", + "UNLOCK", "UNSIGNED", "UPDATE", "USAGE", "USE", "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP", "VALUES", "VARBINARY", "VARCHAR", "VARCHARACTER", "VARYING", "WHEN", "WHERE", "WHILE", "WITH", "WRITE", "X509", "XOR", "YEAR_MONTH", "ZEROFILL"}; String[] sql92Keywords = new String[]{"ABSOLUTE", "EXEC", "OVERLAPS", "ACTION", "EXECUTE", diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessParameterMetaData.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessParameterMetaData.java index 8bb880e3749..e556ba7ac37 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessParameterMetaData.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessParameterMetaData.java @@ -25,7 +25,7 @@ public class VitessParameterMetaData implements ParameterMetaData { private final int parameterCount; /** - * This implementation (and defaults below) is equivalent to mysql-connector-java's "simple" + * This implementation (and defaults below) is equivalent to mysql-connector-j's "simple" * (non-server) statement metadata */ VitessParameterMetaData(int count) { diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java index 550b5180e11..e97b2d151bb 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java @@ -426,7 +426,7 @@ public ParameterMetaData getParameterMetaData() throws SQLException { } /** - * This function was ported from mysql-connector-java ParseInfo object and greatly simplified to + * This function was ported from mysql-connector-j ParseInfo object and greatly simplified to * just the parts for counting parameters */ private int calculateParameterCount() throws SQLException { diff --git a/java/jdbc/src/main/java/io/vitess/util/charset/CharsetMapping.java b/java/jdbc/src/main/java/io/vitess/util/charset/CharsetMapping.java index 343ae0e90eb..8b32e2aab67 100644 --- a/java/jdbc/src/main/java/io/vitess/util/charset/CharsetMapping.java +++ b/java/jdbc/src/main/java/io/vitess/util/charset/CharsetMapping.java @@ -24,7 +24,7 @@ import java.util.Map; /** - * These classes were pulled from mysql-connector-java and simplified to just the parts supporting + * These classes were pulled from mysql-connector-j and simplified to just the parts supporting * the statically available charsets */ public class CharsetMapping { diff --git a/java/jdbc/src/main/java/io/vitess/util/charset/Collation.java b/java/jdbc/src/main/java/io/vitess/util/charset/Collation.java index 31548686655..7bd24d10f2a 100644 --- a/java/jdbc/src/main/java/io/vitess/util/charset/Collation.java +++ b/java/jdbc/src/main/java/io/vitess/util/charset/Collation.java @@ -17,7 +17,7 @@ package io.vitess.util.charset; /** - * These classes were pulled from mysql-connector-java and simplified to just the parts supporting + * These classes were pulled from mysql-connector-j and simplified to just the parts supporting * the statically available charsets */ class Collation { diff --git a/java/jdbc/src/main/java/io/vitess/util/charset/MysqlCharset.java b/java/jdbc/src/main/java/io/vitess/util/charset/MysqlCharset.java index fad94cb8dcb..6691e1cb4b4 100644 --- a/java/jdbc/src/main/java/io/vitess/util/charset/MysqlCharset.java +++ b/java/jdbc/src/main/java/io/vitess/util/charset/MysqlCharset.java @@ -23,7 +23,7 @@ import java.util.Set; /** - * These classes were pulled from mysql-connector-java and simplified to just the parts supporting + * These classes were pulled from mysql-connector-j and simplified to just the parts supporting * the statically available charsets */ class MysqlCharset { diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/FieldWithMetadataTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/FieldWithMetadataTest.java index 26ad5fd11b3..d02dd416d05 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/FieldWithMetadataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/FieldWithMetadataTest.java @@ -28,15 +28,7 @@ import org.junit.Assert; import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.mockito.internal.verification.VerificationModeFactory; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -@PrepareForTest(FieldWithMetadata.class) -@RunWith(PowerMockRunner.class) + public class FieldWithMetadataTest extends BaseTest { @Test @@ -284,7 +276,8 @@ public void testNumericAndDateTimeEncoding() throws SQLException { Query.Type.HEXVAL, Query.Type.HEXNUM, Query.Type.BITNUM, - Query.Type.RAW + Query.Type.RAW, + Query.Type.ROW_TUPLE ); @Test @@ -491,92 +484,6 @@ public void testToString() throws SQLException { Assert.assertEquals(result, field.toString()); } - public void testCollations() throws Exception { - VitessConnection conn = getVitessConnection(); - - Query.Field raw = Query.Field.newBuilder().setTable("foo").setType(Query.Type.CHAR) - .setName("foo").setOrgName("foo").setCharset(33).build(); - - FieldWithMetadata fieldWithMetadata = PowerMockito.spy(new FieldWithMetadata(conn, raw)); - String first = fieldWithMetadata.getCollation(); - String second = fieldWithMetadata.getCollation(); - - Assert.assertEquals("utf8_general_ci", first); - Assert.assertEquals("cached response is same as first", first, second); - - PowerMockito.verifyPrivate(fieldWithMetadata, VerificationModeFactory.times(1)) - .invoke("getCollationIndex"); - - try { - raw = raw.toBuilder() - // value chosen because it's obviously out of bounds for the underlying array - .setCharset(Integer.MAX_VALUE).build(); - - fieldWithMetadata = PowerMockito.spy(new FieldWithMetadata(conn, raw)); - fieldWithMetadata.getCollation(); - Assert.fail("Should have received an array index out of bounds because " - + "charset/collationIndex of Int.MAX is well above size of charset array"); - } catch (SQLException e) { - if (e.getCause() instanceof ArrayIndexOutOfBoundsException) { - Assert.assertEquals("CollationIndex '" + Integer.MAX_VALUE + "' out of bounds for " - + "collationName lookup, should be within 0 and " - + CharsetMapping.COLLATION_INDEX_TO_COLLATION_NAME.length, e.getMessage()); - } else { - // just rethrow so we fail that way - throw e; - } - } - - PowerMockito.verifyPrivate(fieldWithMetadata, VerificationModeFactory.times(1)) - .invoke("getCollationIndex"); - //Mockito.verify(fieldWithMetadata, Mockito.times(1)).getCollationIndex(); - - conn.setIncludedFields(Query.ExecuteOptions.IncludedFields.TYPE_AND_NAME); - fieldWithMetadata = PowerMockito.spy(new FieldWithMetadata(conn, raw)); - Assert.assertEquals("null response when not including all fields", null, - fieldWithMetadata.getCollation()); - - // We should not call this at all, because we're short circuiting due to included fields - //Mockito.verify(fieldWithMetadata, Mockito.never()).getCollationIndex(); - PowerMockito.verifyPrivate(fieldWithMetadata, VerificationModeFactory.times(0)) - .invoke("getCollationIndex"); - } - - @Test - public void testMaxBytesPerChar() throws Exception { - VitessConnection conn = PowerMockito.spy(getVitessConnection()); - - Query.Field raw = Query.Field.newBuilder().setTable("foo").setType(Query.Type.CHAR) - .setName("foo").setOrgName("foo").setCharset(33).build(); - - FieldWithMetadata fieldWithMetadata = PowerMockito.spy(new FieldWithMetadata(conn, raw)); - - int first = fieldWithMetadata.getMaxBytesPerCharacter(); - int second = fieldWithMetadata.getMaxBytesPerCharacter(); - - Assert.assertEquals("cached response is same as first", first, second); - // We called getMaxBytesPerCharacter 2 times above, but should only have made 1 call to - // fieldWithMetadata.getMaxBytesPerChar: - // first - call conn - // second - return cached - Mockito.verify(fieldWithMetadata, VerificationModeFactory.times(1)) - .getMaxBytesPerChar(33, "UTF-8"); - PowerMockito.verifyPrivate(fieldWithMetadata, VerificationModeFactory.times(1)) - .invoke("getCollationIndex"); - - conn.setIncludedFields(Query.ExecuteOptions.IncludedFields.TYPE_AND_NAME); - fieldWithMetadata = PowerMockito.spy(new FieldWithMetadata(conn, raw)); - Assert.assertEquals("0 return value when not including all fields", 0, - fieldWithMetadata.getMaxBytesPerCharacter()); - - // We should not call this function because we short circuited due to not including all fields. - Mockito.verify(fieldWithMetadata, VerificationModeFactory.times(0)) - .getMaxBytesPerChar(33, "UTF-8"); - // Should not be called at all, because it's new for just this test - PowerMockito.verifyPrivate(fieldWithMetadata, VerificationModeFactory.times(0)) - .invoke("getCollationIndex"); - } - @Test public void testGetEncodingForIndex() throws SQLException { Query.Field raw = Query.Field.newBuilder().setTable("foo").setType(Query.Type.CHAR) diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessConnectionTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessConnectionTest.java index 415790ed3f4..e10c97c8636 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessConnectionTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessConnectionTest.java @@ -40,15 +40,11 @@ import java.util.Properties; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.modules.junit4.PowerMockRunner; /** * Created by harshit.gangal on 19/01/16. */ -@RunWith(PowerMockRunner.class) public class VitessConnectionTest extends BaseTest { @Test @@ -118,13 +114,13 @@ public void testDefaultSetAutoCommitForClose() throws SQLException { @Test public void testCommit() throws Exception { - VTSession mockSession = PowerMockito.mock(VTSession.class); + VTSession mockSession = Mockito.mock(VTSession.class); VitessConnection vitessConnection = getVitessConnection(); Field privateVTSessionField = VitessConnection.class.getDeclaredField("vtSession"); privateVTSessionField.setAccessible(true); privateVTSessionField.set(vitessConnection, mockSession); - PowerMockito.when(mockSession.isInTransaction()).thenReturn(false); - PowerMockito.when(mockSession.isAutoCommit()).thenReturn(false); + Mockito.when(mockSession.isInTransaction()).thenReturn(false); + Mockito.when(mockSession.isAutoCommit()).thenReturn(false); vitessConnection.commit(); } @@ -159,13 +155,13 @@ public void testClosed() throws SQLException { @Test(expected = SQLException.class) public void testClosedForException() throws Exception { - VTSession mockSession = PowerMockito.mock(VTSession.class); + VTSession mockSession = Mockito.mock(VTSession.class); VitessConnection vitessConnection = getVitessConnection(); Field privateVTSessionField = VitessConnection.class.getDeclaredField("vtSession"); privateVTSessionField.setAccessible(true); privateVTSessionField.set(vitessConnection, mockSession); - PowerMockito.when(mockSession.isInTransaction()).thenReturn(true); - PowerMockito.when(mockSession.isAutoCommit()).thenReturn(true); + Mockito.when(mockSession.isInTransaction()).thenReturn(true); + Mockito.when(mockSession.isAutoCommit()).thenReturn(true); vitessConnection.close(); } diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java index 92d5cfede9b..e1e50e8a6e6 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java @@ -19,37 +19,26 @@ import com.google.common.base.Charsets; import com.google.common.io.CharStreams; import com.google.protobuf.ByteString; - import io.vitess.client.cursor.Cursor; import io.vitess.client.cursor.SimpleCursor; import io.vitess.proto.Query; import io.vitess.util.Constants; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Types; +import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.Scanner; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - /** * Created by ashudeep.sharma on 08/03/16. */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({VitessMySQLDatabaseMetadata.class, VitessConnection.class}) public class VitessDatabaseMetadataTest extends BaseTest { private ResultSet resultSet; @@ -860,19 +849,19 @@ public void autoCommitFailureClosesAllResultSetsTest() throws SQLException { @Test public void getUrlTest() throws SQLException { String connectionUrl = "jdbc:vitess://://"; - VitessJDBCUrl mockUrl = PowerMockito.mock(VitessJDBCUrl.class); - PowerMockito.when(mockUrl.getUrl()).thenReturn(connectionUrl); + VitessJDBCUrl mockUrl = Mockito.mock(VitessJDBCUrl.class); + Mockito.when(mockUrl.getUrl()).thenReturn(connectionUrl); - VitessConnection mockConn = PowerMockito.mock(VitessConnection.class); - PowerMockito.when(mockConn.getUrl()).thenReturn(mockUrl); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + Mockito.when(mockConn.getUrl()).thenReturn(mockUrl); Assert.assertEquals(connectionUrl, mockConn.getUrl().getUrl()); } @Test public void isReadOnlyTest() throws SQLException { - VitessConnection mockConn = PowerMockito.mock(VitessConnection.class); - PowerMockito.when(mockConn.isReadOnly()).thenReturn(false); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + Mockito.when(mockConn.isReadOnly()).thenReturn(false); Assert.assertEquals(false, mockConn.isReadOnly()); } @@ -1022,74 +1011,6 @@ public void supportsStatementPooling() throws SQLException { Assert.assertEquals(false, vitessMariaDBDatabaseMetadata.supportsStatementPooling()); } - @Test - public void getCatalogsTest() throws SQLException, Exception { - String sql = "SHOW DATABASES"; - Cursor mockedCursor = new SimpleCursor(Query.QueryResult.newBuilder().addFields( - Query.Field.newBuilder().setName("TABLE_CAT").setType(Query.Type.VARCHAR).build()).addRows( - Query.Row.newBuilder().addLengths("vitessDB".length()) - .setValues(ByteString.copyFromUtf8("vitessDB"))).addRows( - Query.Row.newBuilder().addLengths("sampleDB".length()) - .setValues(ByteString.copyFromUtf8("sampleDB"))).addRows( - Query.Row.newBuilder().addLengths("testDB".length()) - .setValues(ByteString.copyFromUtf8("testDB"))).addRows( - Query.Row.newBuilder().addLengths("dummyDB".length()) - .setValues(ByteString.copyFromUtf8("dummyDB"))).build()); - - VitessStatement vitessStatement = PowerMockito.mock(VitessStatement.class); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.when(vitessStatement.executeQuery(sql)) - .thenReturn(new VitessResultSet(mockedCursor)); - - VitessDatabaseMetaData vitessDatabaseMetaData = new VitessMySQLDatabaseMetadata(null); - ResultSet resultSet = vitessDatabaseMetaData.getCatalogs(); - ArrayList resultSetList = new ArrayList(); - while (resultSet.next()) { - resultSetList.add(resultSet.getString(1)); - } - Assert.assertEquals("dummyDB", resultSetList.get(0)); - Assert.assertEquals("sampleDB", resultSetList.get(1)); - Assert.assertEquals("testDB", resultSetList.get(2)); - Assert.assertEquals("vitessDB", resultSetList.get(3)); - } - - @Test - public void getTablesTest() throws SQLException, Exception { - - String sql = "SHOW FULL TABLES FROM `vt` LIKE '%'"; - Cursor mockedCursor = getTablesCursor(); - - VitessStatement vitessStatement = PowerMockito.mock(VitessStatement.class); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.when(vitessStatement.executeQuery(sql)) - .thenReturn(new VitessResultSet(mockedCursor)); - - VitessDatabaseMetaData vitessDatabaseMetaData = new VitessMySQLDatabaseMetadata( - getVitessConnection()); - ResultSet actualResultSet = vitessDatabaseMetaData.getTables("vt", null, null, null); - ResultSet expectedResultSet = new VitessResultSet(mockedCursor); - - assertResultSetEquals(actualResultSet, expectedResultSet); - } - - @Test - public void getTablesProperResultTypeTest() throws SQLException, Exception { - - String sql = "SHOW FULL TABLES FROM `vt` LIKE '%'"; - Cursor mockedCursor = getTablesCursor(); - - VitessStatement vitessStatement = PowerMockito.mock(VitessStatement.class); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.when(vitessStatement.executeQuery(sql)) - .thenReturn(new VitessResultSet(mockedCursor)); - - VitessDatabaseMetaData vitessDatabaseMetaData = new VitessMySQLDatabaseMetadata( - getVitessConnection()); - ResultSet actualResultSet = vitessDatabaseMetaData.getTables("vt", null, null, null); - actualResultSet.next(); - Assert.assertEquals(String.class, actualResultSet.getObject("TABLE_CAT").getClass()); - } - private Cursor getTablesCursor() throws Exception { return new SimpleCursor(Query.QueryResult.newBuilder() .addFields(Query.Field.newBuilder().setName("TABLE_CAT").setType(Query.Type.VARCHAR)) @@ -1131,231 +1052,6 @@ private Cursor getTablesCursor() throws Exception { .build()); } - @Test - public void getColumnsTest() throws SQLException, Exception { - - String sql = "SHOW FULL COLUMNS FROM `sampleTable1` FROM `TestDB1` LIKE '%'"; - Cursor mockedTablecursor = new SimpleCursor(Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("TABLE_CAT").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_SCHEM").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_NAME").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_TYPE").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("REMARKS").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("TYPE_CAT").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("TYPE_SCHEM").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("TYPE_NAME").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("SELF_REFERENCING_COL_NAME") - .setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("REF_GENERATION").setType(Query.Type.VARCHAR)) - .addRows(Query.Row.newBuilder().addLengths("TestDB1".length()).addLengths("".length()) - .addLengths("sampleTable1".length()).addLengths("TABLE".length()) - .addLengths("".length()).addLengths("".length()).addLengths("".length()) - .addLengths("".length()).addLengths("".length()).addLengths("".length()) - .setValues(ByteString.copyFromUtf8("TestDB1sampleTable1TABLE"))).build()); - - Cursor actualCursor = new SimpleCursor(Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("Field").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Type").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Collation").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Null").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Key").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Default").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Extra").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Privileges").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Comment").setType(Query.Type.VARCHAR)).addRows( - Query.Row.newBuilder().addLengths("shipmentid".length()).addLengths("bigint".length()) - .addLengths("NULL".length()).addLengths("NO".length()).addLengths("PRI".length()) - .addLengths("NULL".length()).addLengths("".length()) - .addLengths("select,insert,update,references".length()).addLengths("".length()) - .setValues(ByteString - .copyFromUtf8("shipmentidbigintNULLNOPRINULLselect,insert,update,references"))) - .addRows( - Query.Row.newBuilder().addLengths("trackingid".length()).addLengths("varchar".length()) - .addLengths("utf8_general_ci".length()).addLengths("YES".length()) - .addLengths("".length()).addLengths("NULL".length()).addLengths("".length()) - .addLengths("select,insert,update,references".length()).addLengths("".length()) - .setValues(ByteString.copyFromUtf8( - "trackingidvarcharutf8_general_ciYESNULLselect,insert,update,references"))) - .build()); - Cursor expectedCursor = new SimpleCursor(Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("TABLE_CAT").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_SCHEM").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("COLUMN_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("DATA_TYPE").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("TYPE_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("COLUMN_SIZE").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("BUFFER_LENGTH").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("DECIMAL_DIGITS").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("NUM_PREC_RADIX").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("NULLABLE").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("REMARKS").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("COLUMN_DEF").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("SQL_DATA_TYPE").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("SQL_DATETIME_SUB").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("CHAR_OCTET_LENGTH").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("ORDINAL_POSITION").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("ISNULLABLE").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("SCOPE_CATALOG").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("SCOPE_SCHEMA").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("SCOPE_TABLE").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("SOURCE_DATA_TYPE").setType(Query.Type.INT16)) - .addFields(Query.Field.newBuilder().setName("IS_AUTOINCREMENT").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("IS_GENERATEDCOLUMN").setType(Query.Type.CHAR)) - .addRows(Query.Row.newBuilder().addLengths("TestDB1".length()).addLengths(-1) - .addLengths("sampleTable1".length()).addLengths("shipmentid".length()) - .addLengths("-5".length()).addLengths("BIGINT".length()).addLengths("19".length()) - .addLengths("65535".length()).addLengths("0".length()).addLengths("10".length()) - .addLengths("0".length()).addLengths("Comment".length()).addLengths("NULL".length()) - .addLengths("0".length()).addLengths("0".length()).addLengths("0".length()) - .addLengths("1".length()).addLengths("NO".length()).addLengths(-1).addLengths(-1) - .addLengths(-1).addLengths(-1).addLengths("NO".length()).addLengths("NO".length()) - .setValues(ByteString.copyFromUtf8( - "TestDB1sampleTable1shipmentid-5BIGINT19655350100CommentNULL0001NONONO"))).addRows( - Query.Row.newBuilder().addLengths("TestDB1".length()).addLengths(-1) - .addLengths("sampleTable1".length()).addLengths("trackingid".length()) - .addLengths("12".length()).addLengths("VARCHAR".length()).addLengths("255".length()) - .addLengths("65535".length()).addLengths(-1).addLengths("10".length()) - .addLengths("1".length()).addLengths("Comment".length()).addLengths("NULL".length()) - .addLengths("0".length()).addLengths("0".length()).addLengths("255".length()) - .addLengths("2".length()).addLengths("YES".length()).addLengths(-1).addLengths(-1) - .addLengths(-1).addLengths(-1).addLengths("NO".length()).addLengths("NO".length()) - .setValues(ByteString.copyFromUtf8( - "TestDB1sampleTable1trackingid12VARCHAR25565535101CommentNULL002552YESNONO"))) - .build()); - - VitessStatement vitessStatement = PowerMockito.mock(VitessStatement.class); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.when(vitessStatement.executeQuery(sql)) - .thenReturn(new VitessResultSet(actualCursor)); - - VitessDatabaseMetaData vitessDatabaseMetaData = PowerMockito - .mock(VitessMySQLDatabaseMetadata.class); - PowerMockito.doCallRealMethod().when(vitessDatabaseMetaData) - .getColumns("TestDB1", null, null, null); - PowerMockito.when(vitessDatabaseMetaData.getTables("TestDB1", null, "%", new String[0])) - .thenReturn(new VitessResultSet(mockedTablecursor)); - ResultSet actualResultSet = vitessDatabaseMetaData.getColumns("TestDB1", null, null, null); - ResultSet expectedResultSet = new VitessResultSet(expectedCursor); - - assertResultSetEquals(actualResultSet, expectedResultSet); - } - - @Test - public void getPrimaryKeysTest() throws SQLException, Exception { - - String sql = "SHOW KEYS FROM `shipment` FROM `vt`"; - Cursor mockedCursor = new SimpleCursor(Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("TABLE").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Non_unique").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Key_name").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Seq_in_index").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Column_name").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Collation").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Cardinality").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Sub_part").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Packed").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Null").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Index_type").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Comment").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Index_comment").setType(Query.Type.VARCHAR)) - .addRows(Query.Row.newBuilder().addLengths("shipment".length()).addLengths("0".length()) - .addLengths("PRIMARY".length()).addLengths("1".length()) - .addLengths("shipmentid".length()).addLengths("A".length()) - .addLengths("434880".length()).addLengths(-1).addLengths(-1).addLengths("".length()) - .addLengths("BTREE".length()).addLengths("".length()).addLengths("".length()) - .setValues(ByteString.copyFromUtf8("shipment0PRIMARY1shipmentidA434880BTREE"))) - .build()); - Cursor expectedcursor = new SimpleCursor(Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("TABLE_CAT").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_SCHEM").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("COLUMN_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("KEY_SEQ").setType(Query.Type.INT16)) - .addFields(Query.Field.newBuilder().setName("PK_NAME").setType(Query.Type.CHAR)).addRows( - Query.Row.newBuilder().addLengths("vt".length()).addLengths(-1) - .addLengths("shipment".length()).addLengths("shipmentid".length()) - .addLengths("1".length()).addLengths("PRIMARY".length()) - .setValues(ByteString.copyFromUtf8("vtshipmentshipmentid1PRIMARY"))).build()); - - VitessStatement vitessStatement = PowerMockito.mock(VitessStatement.class); - VitessDatabaseMetaData vitessDatabaseMetaData = PowerMockito - .mock(VitessMySQLDatabaseMetadata.class); - PowerMockito.mock(VitessMySQLDatabaseMetadata.class); - PowerMockito.doCallRealMethod().when(vitessDatabaseMetaData) - .getPrimaryKeys("vt", null, "shipment"); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.when(vitessStatement.executeQuery(sql)) - .thenReturn(new VitessResultSet(mockedCursor)); - ResultSet expectedResultSet = vitessDatabaseMetaData.getPrimaryKeys("vt", null, "shipment"); - ResultSet actualResultSet = new VitessResultSet(expectedcursor); - - assertResultSetEquals(actualResultSet, expectedResultSet); - } - - @Test - public void getIndexInfoTest() throws SQLException, Exception { - - String sql = "SHOW INDEX FROM `shipment` FROM `vt`"; - Cursor mockedCursor = new SimpleCursor(Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("Table").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Non_unique").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Key_name").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Seq_in_index").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Column_name").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Collation").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Cardinality").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Sub_part").setType(Query.Type.INT64)) - .addFields(Query.Field.newBuilder().setName("Packed").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Null").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Index_type").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Comment").setType(Query.Type.VARCHAR)) - .addFields(Query.Field.newBuilder().setName("Index_comment").setType(Query.Type.VARCHAR)) - .addRows(Query.Row.newBuilder().addLengths("shipment".length()).addLengths("0".length()) - .addLengths("PRIMARY".length()).addLengths("1".length()) - .addLengths("shipmentid".length()).addLengths("A".length()) - .addLengths("434880".length()).addLengths(-1).addLengths(-1).addLengths("".length()) - .addLengths("BTREE".length()).addLengths("".length()).addLengths("".length()) - .setValues(ByteString.copyFromUtf8("shipment0PRIMARY1shipmentidA434880BTREE"))) - .build()); - - Cursor expectedcursor = new SimpleCursor(Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("TABLE_CAT").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_SCHEM").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("TABLE_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("Non_unique").setType(Query.Type.BIT)) - .addFields(Query.Field.newBuilder().setName("INDEX_QUALIFIER").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("INDEX_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("TYPE").setType(Query.Type.INT16)) - .addFields(Query.Field.newBuilder().setName("ORDINAL_POSITION").setType(Query.Type.INT16)) - .addFields(Query.Field.newBuilder().setName("COLUMN_NAME").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("ASC_OR_DESC").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("CARDINALITY").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("PAGES").setType(Query.Type.INT32)) - .addFields(Query.Field.newBuilder().setName("FILTER_CONDITION").setType(Query.Type.CHAR)) - .addRows(Query.Row.newBuilder().addLengths("vt".length()).addLengths(-1) - .addLengths("shipment".length()).addLengths("false".length()).addLengths("".length()) - .addLengths("PRIMARY".length()).addLengths("3".length()).addLengths("1".length()) - .addLengths("shipmentid".length()).addLengths("A".length()) - .addLengths("434880".length()).addLengths("0".length()).addLengths(-1) - .setValues(ByteString.copyFromUtf8("vtshipmentfalsePRIMARY31shipmentidA4348800"))) - .build()); - VitessStatement vitessStatement = PowerMockito.mock(VitessStatement.class); - VitessDatabaseMetaData vitessDatabaseMetaData = PowerMockito - .mock(VitessMySQLDatabaseMetadata.class); - PowerMockito.mock(VitessMySQLDatabaseMetadata.class); - PowerMockito.doCallRealMethod().when(vitessDatabaseMetaData) - .getIndexInfo("vt", null, "shipment", true, false); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.when(vitessStatement.executeQuery(sql)) - .thenReturn(new VitessResultSet(mockedCursor)); - ResultSet actualResultSet = vitessDatabaseMetaData - .getIndexInfo("vt", null, "shipment", true, false); - ResultSet expectedResultSet = new VitessResultSet(expectedcursor); - - assertResultSetEquals(actualResultSet, expectedResultSet); - } - private void assertResultSetEquals(ResultSet actualResultSet, ResultSet expectedResultSet) throws SQLException { ResultSetMetaData actualResultSetMetadata = actualResultSet.getMetaData(); @@ -1440,137 +1136,6 @@ public void getUserNameTest() { } } - @Test - public void testCaseSensitivityIdentifierFuncsMySql() throws Exception { - assertCaseSensitivityForDatabaseType(false); - } - - @Test - public void testCaseSensitivityIdentifierFuncsMariaDb() throws Exception { - assertCaseSensitivityForDatabaseType(true); - } - - private void assertCaseSensitivityForDatabaseType(boolean useMariaDb) throws Exception { - VitessConnection connection = new VitessConnection("jdbc:vitess://username@ip1:port1/keyspace", - null); - mockStatementForLowercaseTablesValue("0", useMariaDb); - Assert.assertEquals(true, connection.getMetaData().supportsMixedCaseIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().supportsMixedCaseQuotedIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesLowerCaseIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesMixedCaseIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesLowerCaseQuotedIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesMixedCaseQuotedIdentifiers()); - connection.close(); - - connection = new VitessConnection("jdbc:vitess://username@ip1:port1/keyspace", null); - mockStatementForLowercaseTablesValue("1", useMariaDb); - Assert.assertEquals(false, connection.getMetaData().supportsMixedCaseIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().supportsMixedCaseQuotedIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesLowerCaseIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesMixedCaseIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesLowerCaseQuotedIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesMixedCaseQuotedIdentifiers()); - connection.close(); - - connection = new VitessConnection("jdbc:vitess://username@ip1:port1/keyspace", null); - mockStatementForLowercaseTablesValue("2", useMariaDb); - Assert.assertEquals(false, connection.getMetaData().supportsMixedCaseIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().supportsMixedCaseQuotedIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesLowerCaseIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesMixedCaseIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesLowerCaseQuotedIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesMixedCaseQuotedIdentifiers()); - connection.close(); - - connection = new VitessConnection("jdbc:vitess://username@ip1:port1/keyspace", null); - mockStatementForLowercaseTablesValue("something random", useMariaDb); - Assert.assertEquals(true, connection.getMetaData().supportsMixedCaseIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().supportsMixedCaseQuotedIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesLowerCaseIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesMixedCaseIdentifiers()); - Assert.assertEquals(false, connection.getMetaData().storesLowerCaseQuotedIdentifiers()); - Assert.assertEquals(true, connection.getMetaData().storesMixedCaseQuotedIdentifiers()); - connection.close(); - } - - private void mockStatementForLowercaseTablesValue(String lcTablesValue, boolean useMariaDb) - throws Exception { - String sql = "SHOW VARIABLES WHERE VARIABLE_NAME IN (\'tx_isolation\',\'INNODB_VERSION\', " - + "\'lower_case_table_names\')"; - String versionName = "innodb_version"; - String versionValue = "5.7.16-10"; - if (useMariaDb) { - versionValue = versionValue + "-mariadb"; - } - String txIsoName = "tx_isolation"; - String txIsoValue = "REPEATABLE-READ"; - String lcTablesName = "lower_case_table_names"; - - Cursor mockedCursor = new SimpleCursor(Query.QueryResult.newBuilder().addFields( - Query.Field.newBuilder().setName("Variable_name").setType(Query.Type.VARCHAR).build()) - .addFields(Query.Field.newBuilder().setName("Value").setType(Query.Type.VARCHAR).build()) - .addRows(Query.Row.newBuilder().addLengths(versionName.length()) - .addLengths(versionValue.length()) - .setValues(ByteString.copyFromUtf8(versionName + versionValue))).addRows( - Query.Row.newBuilder().addLengths(txIsoName.length()).addLengths(txIsoValue.length()) - .setValues(ByteString.copyFromUtf8(txIsoName + txIsoValue))).addRows( - Query.Row.newBuilder().addLengths(lcTablesName.length()) - .addLengths(lcTablesValue.length()) - .setValues(ByteString.copyFromUtf8(lcTablesName + lcTablesValue))).build()); - - VitessStatement vitessStatement = PowerMockito.mock(VitessStatement.class); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.when(vitessStatement.executeQuery(sql)) - .thenReturn(new VitessResultSet(mockedCursor)); - } - - /** - * Tests that we're properly stitching together the results of SHOW CREATE TABLE. See {@link - * #extractForeignKeyForTableTest()} for more thorough testing of the actual parsing - */ - @Test - public void getImportedKeysTest() throws Exception { - try (InputStream resourceAsStream = this.getClass() - .getResourceAsStream("/getImportedKeysTestCase.sql")) { - String table = "testA"; - String showCreate = CharStreams - .toString(new InputStreamReader(resourceAsStream, Charsets.UTF_8)); - - Query.QueryResult queryResult = Query.QueryResult.newBuilder() - .addFields(Query.Field.newBuilder().setName("Table").setType(Query.Type.CHAR)) - .addFields(Query.Field.newBuilder().setName("Create Table").setType(Query.Type.CHAR)) - .addRows(Query.Row.newBuilder().addLengths(table.length()).addLengths(showCreate.length()) - .setValues(ByteString.copyFromUtf8(table + showCreate))).build(); - - String sql = "SHOW CREATE TABLE `testA`"; - VitessConnection vitessConnection = new VitessConnection( - "jdbc:vitess://username@ip1:port1/keyspace", null); - VitessStatement vitessStatement = PowerMockito.spy(new VitessStatement(vitessConnection)); - PowerMockito.whenNew(VitessStatement.class).withAnyArguments().thenReturn(vitessStatement); - PowerMockito.doReturn(new VitessResultSet(new SimpleCursor(queryResult), vitessStatement)) - .when(vitessStatement).executeQuery(sql); - - VitessDatabaseMetaData vitessDatabaseMetaData = new VitessMySQLDatabaseMetadata( - vitessConnection); - ResultSet importedKeys = vitessDatabaseMetaData.getImportedKeys("test", "test", "testA"); - importedKeys.next(); - Assert.assertEquals("test", importedKeys.getString("PKTABLE_CAT")); - Assert.assertEquals(null, importedKeys.getString("PKTABLE_SCHEM")); - Assert.assertEquals("fTable", importedKeys.getString("PKTABLE_NAME")); - Assert.assertEquals("id", importedKeys.getString("PKCOLUMN_NAME")); - Assert.assertEquals("test", importedKeys.getString("FKTABLE_CAT")); - Assert.assertEquals(null, importedKeys.getString("FKTABLE_SCHEM")); - Assert.assertEquals("testA", importedKeys.getString("FKTABLE_NAME")); - Assert.assertEquals("fIdOne", importedKeys.getString("FKCOLUMN_NAME")); - Assert.assertEquals(1, importedKeys.getInt("KEY_SEQ")); - Assert.assertEquals(3, importedKeys.getInt("UPDATE_RULE")); - Assert.assertEquals(3, importedKeys.getInt("DELETE_RULE")); - Assert.assertEquals("fk_testA", importedKeys.getString("FK_NAME")); - Assert.assertEquals(null, importedKeys.getString("PK_NAME")); - Assert.assertEquals(7, importedKeys.getInt("DEFERRABILITY")); - } - } - /** * Tests parsing all the various outputs of SHOW CREATE TABLE for the foreign key constraints. */ diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessParameterMetaDataTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessParameterMetaDataTest.java index 8916063ffaf..890212d5071 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessParameterMetaDataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessParameterMetaDataTest.java @@ -16,20 +16,13 @@ package io.vitess.jdbc; +import org.junit.Assert; +import org.junit.Test; + import java.sql.ParameterMetaData; import java.sql.SQLException; import java.sql.Types; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.internal.verification.VerificationModeFactory; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@PrepareForTest(VitessParameterMetaData.class) public class VitessParameterMetaDataTest { @Test @@ -70,22 +63,6 @@ public void testOutOfBoundsValidation() { } } - @Test - public void testOutOfBoundCoverage() throws Exception { - int param = 2; - VitessParameterMetaData metaData = PowerMockito.spy(new VitessParameterMetaData(5)); - - metaData.getParameterType(param); - metaData.getPrecision(param); - metaData.getScale(param); - metaData.getParameterClassName(param); - metaData.getParameterTypeName(param); - metaData.isSigned(param); - - PowerMockito.verifyPrivate(metaData, VerificationModeFactory.times(6)) - .invoke("checkBounds", param); - } - @Test(expected = SQLException.class) public void testNullableNotAvailable() throws SQLException { VitessParameterMetaData metaData = new VitessParameterMetaData(5); diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java index c5a9b4cbd33..2ebadf371ec 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java @@ -18,12 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; import static org.mockito.Matchers.nullable; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.when; import com.google.common.collect.ImmutableMap; @@ -59,19 +54,13 @@ import org.junit.Assert; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mockito; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; /** * Created by harshit.gangal on 09/02/16. */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({VTGateConnection.class, Vtrpc.RPCError.class}) public class VitessPreparedStatementTest { private String sqlSelect = "select 1 from test_table"; @@ -81,7 +70,7 @@ public class VitessPreparedStatementTest { @Test public void testStatementExecute() { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessPreparedStatement preparedStatement; try { preparedStatement = new VitessPreparedStatement(mockConn, sqlShow); @@ -110,17 +99,17 @@ public void testStatementExecute() { @Test public void testExecuteQuery() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))). + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))). thenReturn(mockSqlFutureCursor); - when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); - when(mockConn.isSimpleExecute()).thenReturn(true); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(true); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); VitessPreparedStatement preparedStatement; try { @@ -156,7 +145,7 @@ public void testExecuteQuery() throws SQLException { try { //when returned cursor is null - when(mockSqlFutureCursor.checkedGet()).thenReturn(null); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(null); preparedStatement.executeQuery(); fail("Should have thrown exception for cursor null"); } catch (SQLException ex) { @@ -170,19 +159,19 @@ public void testExecuteQuery() throws SQLException { @Test public void testExecuteQueryWithStream() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn .streamExecute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockCursor); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.STREAM); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.STREAM); VitessPreparedStatement preparedStatement; try { @@ -218,7 +207,7 @@ public void testExecuteQueryWithStream() throws SQLException { try { //when returned cursor is null - when(mockVtGateConn + Mockito.when(mockVtGateConn .streamExecute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(null); preparedStatement.executeQuery(); @@ -235,17 +224,17 @@ public void testExecuteQueryWithStream() throws SQLException { @Test public void testExecuteUpdate() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - List fieldList = mock(ArrayList.class); - - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + List fieldList = Mockito.mock(ArrayList.class); + + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); VitessPreparedStatement preparedStatement; try { @@ -257,14 +246,14 @@ public void testExecuteUpdate() throws SQLException { assertEquals(0, updateCount); //tx is null & autoCommit is true - when(mockConn.getAutoCommit()).thenReturn(true); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); preparedStatement = new VitessPreparedStatement(mockConn, sqlUpdate); updateCount = preparedStatement.executeUpdate(); assertEquals(0, updateCount); //cursor fields is not null - when(mockCursor.getFields()).thenReturn(fieldList); - when(fieldList.isEmpty()).thenReturn(false); + Mockito.when(mockCursor.getFields()).thenReturn(fieldList); + Mockito.when(fieldList.isEmpty()).thenReturn(false); try { preparedStatement.executeUpdate(); fail("Should have thrown exception for field not null"); @@ -273,7 +262,7 @@ public void testExecuteUpdate() throws SQLException { } //cursor is null - when(mockSqlFutureCursor.checkedGet()).thenReturn(null); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(null); try { preparedStatement.executeUpdate(); fail("Should have thrown exception for cursor null"); @@ -282,7 +271,7 @@ public void testExecuteUpdate() throws SQLException { } //read only - when(mockConn.isReadOnly()).thenReturn(true); + Mockito.when(mockConn.isReadOnly()).thenReturn(true); try { preparedStatement.executeUpdate(); fail("Should have thrown exception for read only"); @@ -291,7 +280,7 @@ public void testExecuteUpdate() throws SQLException { } //read only - when(mockConn.isReadOnly()).thenReturn(true); + Mockito.when(mockConn.isReadOnly()).thenReturn(true); try { preparedStatement.executeBatch(); fail("Should have thrown exception for read only"); @@ -306,31 +295,31 @@ public void testExecuteUpdate() throws SQLException { @Test public void testExecute() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - List mockFieldList = PowerMockito.spy(new ArrayList<>()); - - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + List mockFieldList = Mockito.spy(new ArrayList<>()); + + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); - when(mockConn.isSimpleExecute()).thenReturn(true); + Mockito.when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(true); - when(mockConn.getAutoCommit()).thenReturn(true); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(mockFieldList); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(mockFieldList); VitessPreparedStatement preparedStatement = new VitessPreparedStatement(mockConn, sqlSelect, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); try { int fieldSize = 5; - when(mockCursor.getFields()).thenReturn(mockFieldList); - PowerMockito.doReturn(fieldSize).when(mockFieldList).size(); - PowerMockito.doReturn(false).when(mockFieldList).isEmpty(); + Mockito.when(mockCursor.getFields()).thenReturn(mockFieldList); + Mockito.doReturn(fieldSize).when(mockFieldList).size(); + Mockito.doReturn(false).when(mockFieldList).isEmpty(); boolean hasResultSet = preparedStatement.execute(); Assert.assertTrue(hasResultSet); Assert.assertNotNull(preparedStatement.getResultSet()); @@ -341,9 +330,9 @@ public void testExecute() throws SQLException { Assert.assertNotNull(preparedStatement.getResultSet()); int mockUpdateCount = 10; - when(mockCursor.getFields()) + Mockito.when(mockCursor.getFields()) .thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); - when(mockCursor.getRowsAffected()).thenReturn((long) mockUpdateCount); + Mockito.when(mockCursor.getRowsAffected()).thenReturn((long) mockUpdateCount); preparedStatement = new VitessPreparedStatement(mockConn, sqlUpdate); hasResultSet = preparedStatement.execute(); Assert.assertFalse(hasResultSet); @@ -351,7 +340,7 @@ public void testExecute() throws SQLException { assertEquals(mockUpdateCount, preparedStatement.getUpdateCount()); //cursor is null - when(mockSqlFutureCursor.checkedGet()).thenReturn(null); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(null); try { preparedStatement = new VitessPreparedStatement(mockConn, sqlShow); preparedStatement.execute(); @@ -375,19 +364,19 @@ public void testExecuteFetchSizeAsStreaming() throws SQLException { private void testExecute(int fetchSize, boolean simpleExecute, boolean shouldRunExecute, boolean shouldRunStreamExecute) throws SQLException { - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); - VitessConnection mockConn = mock(VitessConnection.class); - when(mockConn.isSimpleExecute()).thenReturn(simpleExecute); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(simpleExecute); + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockVtGateConn + Mockito.when(mockVtGateConn .streamExecute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockCursor); @@ -408,32 +397,32 @@ private void testExecute(int fetchSize, boolean simpleExecute, boolean shouldRun @Test public void testGetUpdateCount() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFuture = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFuture = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFuture); - when(mockSqlFuture.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFuture.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); VitessPreparedStatement preparedStatement = new VitessPreparedStatement(mockConn, sqlSelect); try { - when(mockCursor.getRowsAffected()).thenReturn(10L); + Mockito.when(mockCursor.getRowsAffected()).thenReturn(10L); int updateCount = preparedStatement.executeUpdate(); assertEquals(10L, updateCount); assertEquals(10L, preparedStatement.getUpdateCount()); // Truncated Update Count - when(mockCursor.getRowsAffected()).thenReturn((long) Integer.MAX_VALUE + 10); + Mockito.when(mockCursor.getRowsAffected()).thenReturn((long) Integer.MAX_VALUE + 10); updateCount = preparedStatement.executeUpdate(); assertEquals(Integer.MAX_VALUE, updateCount); assertEquals(Integer.MAX_VALUE, preparedStatement.getUpdateCount()); - when(mockConn.isSimpleExecute()).thenReturn(true); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(true); preparedStatement.executeQuery(); assertEquals(-1, preparedStatement.getUpdateCount()); @@ -444,7 +433,7 @@ public void testGetUpdateCount() throws SQLException { @Test public void testSetParameters() throws Exception { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); Mockito.when(mockConn.getTreatUtilDateAsTimestamp()).thenReturn(true); VitessPreparedStatement preparedStatement = new VitessPreparedStatement(mockConn, sqlSelect); Boolean boolValue = true; @@ -565,7 +554,7 @@ public void testSetParameters() throws Exception { @Test public void testTreatUtilDateAsTimestamp() throws Exception { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessPreparedStatement preparedStatement = new VitessPreparedStatement(mockConn, sqlSelect); java.util.Date utilDateValue = new java.util.Date(System.currentTimeMillis()); @@ -593,24 +582,24 @@ public void testTreatUtilDateAsTimestamp() throws Exception { @Test public void testAutoGeneratedKeys() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); try { long expectedFirstGeneratedId = 121; long[] expectedGeneratedIds = {121, 122}; int expectedAffectedRows = 2; - when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); - when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedAffectedRows)); + Mockito.when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); + Mockito.when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedAffectedRows)); //Executing Insert Statement VitessPreparedStatement preparedStatement = new VitessPreparedStatement(mockConn, sqlInsert, @@ -632,7 +621,7 @@ public void testAutoGeneratedKeys() throws SQLException { @Test public void testAddBatch() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessPreparedStatement statement = new VitessPreparedStatement(mockConn, sqlInsert); try { statement.addBatch(this.sqlInsert); @@ -656,7 +645,7 @@ public void testAddBatch() throws SQLException { @Test public void testClearBatch() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessPreparedStatement statement = new VitessPreparedStatement(mockConn, sqlInsert); statement.setString(1, "string1"); statement.addBatch(); @@ -674,25 +663,25 @@ public void testClearBatch() throws SQLException { @Test public void testExecuteBatch() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessPreparedStatement statement = new VitessPreparedStatement(mockConn, sqlInsert); int[] updateCounts = statement.executeBatch(); assertEquals(0, updateCounts.length); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockConn.getAutoCommit()).thenReturn(true); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - when(mockVtGateConn.executeBatch(nullable(Context.class), Matchers.anyList(), Matchers.anyList(), + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + Mockito.when(mockVtGateConn.executeBatch(nullable(Context.class), Matchers.anyList(), Matchers.anyList(), nullable(VTSession.class))).thenReturn(mockSqlFutureCursor); List mockCursorWithErrorList = new ArrayList<>(); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); - CursorWithError mockCursorWithError1 = mock(CursorWithError.class); - when(mockCursorWithError1.getError()).thenReturn(null); - when(mockCursorWithError1.getCursor()).thenReturn(mock(Cursor.class)); + CursorWithError mockCursorWithError1 = Mockito.mock(CursorWithError.class); + Mockito.when(mockCursorWithError1.getError()).thenReturn(null); + Mockito.when(mockCursorWithError1.getCursor()).thenReturn(Mockito.mock(Cursor.class)); mockCursorWithErrorList.add(mockCursorWithError1); statement.setString(1, "string1"); @@ -700,10 +689,10 @@ public void testExecuteBatch() throws SQLException { updateCounts = statement.executeBatch(); assertEquals(1, updateCounts.length); - CursorWithError mockCursorWithError2 = mock(CursorWithError.class); + CursorWithError mockCursorWithError2 = Mockito.mock(CursorWithError.class); Vtrpc.RPCError rpcError = Vtrpc.RPCError.newBuilder() .setMessage("preparedStatement execute batch error").build(); - when(mockCursorWithError2.getError()).thenReturn(rpcError); + Mockito.when(mockCursorWithError2.getError()).thenReturn(rpcError); mockCursorWithErrorList.add(mockCursorWithError2); statement.setString(1, "string1"); statement.addBatch(); @@ -721,7 +710,7 @@ public void testExecuteBatch() throws SQLException { @Test public void testStatementCount() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); Map testCases = ImmutableMap.builder() .put("select * from foo where a = ?", 1).put("select * from foo where a = ? and b = ?", 2) .put("select * from foo where a = ? and b = \"?\"", 1) diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java index a2be875e0d0..bd753d2fcb5 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java @@ -40,18 +40,13 @@ import org.junit.Assert; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Matchers; +import org.mockito.Mockito; import org.mockito.internal.verification.VerificationModeFactory; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; /** * Created by harshit.gangal on 19/01/16. */ -@RunWith(PowerMockRunner.class) -@PrepareForTest(VitessResultSet.class) public class VitessResultSetTest extends BaseTest { public Cursor getCursorWithRows() { @@ -635,230 +630,6 @@ public void testEnhancedFieldsFromCursor() throws Exception { assertEquals(cursor.getFields().size(), vitessResultSet.getFields().size()); } - @Test - public void testGetStringUsesEncoding() throws Exception { - VitessConnection conn = getVitessConnection(); - VitessResultSet resultOne = PowerMockito - .spy(new VitessResultSet(getCursorWithRows(), new VitessStatement(conn))); - resultOne.next(); - // test all ways to get to convertBytesToString - - // Verify that we're going through convertBytesToString for column types that return bytes - // (string-like), - // but not for those that return a real object - //resultOne.getString("col21"); // is a string, should go through convert bytes - //resultOne.getString("col13"); // is a datetime, should not - //PowerMockito.verifyPrivate(resultOne, VerificationModeFactory.times(1)) - // .invoke("convertBytesToString", Matchers.any(byte[].class), Matchers.anyString()); - - conn.setIncludedFields(Query.ExecuteOptions.IncludedFields.TYPE_AND_NAME); - VitessResultSet resultTwo = PowerMockito - .spy(new VitessResultSet(getCursorWithRows(), new VitessStatement(conn))); - resultTwo.next(); - - // neither of these should go through convertBytesToString, because we didn't include all fields - resultTwo.getString("col21"); - resultTwo.getString("col13"); - PowerMockito.verifyPrivate(resultTwo, VerificationModeFactory.times(0)) - .invoke("convertBytesToString", Matchers.any(byte[].class), Matchers.anyString()); - } - - @Test - public void testGetObjectForBitValues() throws Exception { - VitessConnection conn = getVitessConnection(); - - ByteString.Output value = ByteString.newOutput(); - value.write(new byte[]{1}); - value.write(new byte[]{0}); - value.write(new byte[]{1, 2, 3, 4}); - - Query.QueryResult result = Query.QueryResult.newBuilder().addFields( - Query.Field.newBuilder().setName("col1").setColumnLength(1).setType(Query.Type.BIT)) - .addFields( - Query.Field.newBuilder().setName("col2").setColumnLength(1).setType(Query.Type.BIT)) - .addFields( - Query.Field.newBuilder().setName("col3").setColumnLength(4).setType(Query.Type.BIT)) - .addRows(Query.Row.newBuilder().addLengths(1).addLengths(1).addLengths(4) - .setValues(value.toByteString())).build(); - - VitessResultSet vitessResultSet = PowerMockito - .spy(new VitessResultSet(new SimpleCursor(result), new VitessStatement(conn))); - vitessResultSet.next(); - - assertEquals(true, vitessResultSet.getObject(1)); - assertEquals(false, vitessResultSet.getObject(2)); - Assert.assertArrayEquals(new byte[]{1, 2, 3, 4}, (byte[]) vitessResultSet.getObject(3)); - - PowerMockito.verifyPrivate(vitessResultSet, VerificationModeFactory.times(3)) - .invoke("convertBytesIfPossible", Matchers.any(byte[].class), - Matchers.any(FieldWithMetadata.class)); - - conn.setIncludedFields(Query.ExecuteOptions.IncludedFields.TYPE_AND_NAME); - vitessResultSet = PowerMockito - .spy(new VitessResultSet(new SimpleCursor(result), new VitessStatement(conn))); - vitessResultSet.next(); - - Assert.assertArrayEquals(new byte[]{1}, (byte[]) vitessResultSet.getObject(1)); - Assert.assertArrayEquals(new byte[]{0}, (byte[]) vitessResultSet.getObject(2)); - Assert.assertArrayEquals(new byte[]{1, 2, 3, 4}, (byte[]) vitessResultSet.getObject(3)); - - PowerMockito.verifyPrivate(vitessResultSet, VerificationModeFactory.times(0)) - .invoke("convertBytesIfPossible", Matchers.any(byte[].class), - Matchers.any(FieldWithMetadata.class)); - } - - @Test - public void testGetObjectForVarBinLikeValues() throws Exception { - VitessConnection conn = getVitessConnection(); - - ByteString.Output value = ByteString.newOutput(); - - byte[] binary = new byte[]{1, 2, 3, 4}; - byte[] varbinary = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; - byte[] blob = new byte[MysqlDefs.LENGTH_BLOB]; - for (int i = 0; i < blob.length; i++) { - blob[i] = 1; - } - byte[] fakeGeometry = new byte[]{2, 3, 4}; - - value.write(binary); - value.write(varbinary); - value.write(blob); - value.write(fakeGeometry); - - Query.QueryResult result = Query.QueryResult.newBuilder().addFields( - Query.Field.newBuilder().setName("col1").setColumnLength(4) - .setCharset(CharsetMapping.MYSQL_COLLATION_INDEX_binary).setType(Query.Type.BINARY) - .setFlags(Query.MySqlFlag.BINARY_FLAG_VALUE)).addFields( - Query.Field.newBuilder().setName("col2").setColumnLength(13) - .setCharset(CharsetMapping.MYSQL_COLLATION_INDEX_binary).setType(Query.Type.VARBINARY) - .setFlags(Query.MySqlFlag.BINARY_FLAG_VALUE)).addFields( - Query.Field.newBuilder().setName("col3") // should go to LONGVARBINARY due to below settings - .setColumnLength(MysqlDefs.LENGTH_BLOB) - .setCharset(CharsetMapping.MYSQL_COLLATION_INDEX_binary) - .setFlags(Query.MySqlFlag.BINARY_FLAG_VALUE).setType(Query.Type.BLOB)).addFields( - Query.Field.newBuilder().setName("col4").setType(Query.Type.GEOMETRY) - .setCharset(CharsetMapping.MYSQL_COLLATION_INDEX_binary).setType(Query.Type.BINARY) - .setFlags(Query.MySqlFlag.BINARY_FLAG_VALUE)).addRows( - Query.Row.newBuilder().addLengths(4).addLengths(13).addLengths(MysqlDefs.LENGTH_BLOB) - .addLengths(3).setValues(value.toByteString())).build(); - - VitessResultSet vitessResultSet = PowerMockito - .spy(new VitessResultSet(new SimpleCursor(result), new VitessStatement(conn))); - vitessResultSet.next(); - - // All of these types should pass straight through, returning the direct bytes - Assert.assertArrayEquals(binary, (byte[]) vitessResultSet.getObject(1)); - Assert.assertArrayEquals(varbinary, (byte[]) vitessResultSet.getObject(2)); - Assert.assertArrayEquals(blob, (byte[]) vitessResultSet.getObject(3)); - Assert.assertArrayEquals(fakeGeometry, (byte[]) vitessResultSet.getObject(4)); - - // We should still call the function 4 times - PowerMockito.verifyPrivate(vitessResultSet, VerificationModeFactory.times(4)) - .invoke("convertBytesIfPossible", Matchers.any(byte[].class), - Matchers.any(FieldWithMetadata.class)); - - conn.setIncludedFields(Query.ExecuteOptions.IncludedFields.TYPE_AND_NAME); - vitessResultSet = PowerMockito - .spy(new VitessResultSet(new SimpleCursor(result), new VitessStatement(conn))); - vitessResultSet.next(); - - // Same as above since this doesn't really do much but pass right through for the varbinary type - Assert.assertArrayEquals(binary, (byte[]) vitessResultSet.getObject(1)); - Assert.assertArrayEquals(varbinary, (byte[]) vitessResultSet.getObject(2)); - Assert.assertArrayEquals(blob, (byte[]) vitessResultSet.getObject(3)); - Assert.assertArrayEquals(fakeGeometry, (byte[]) vitessResultSet.getObject(4)); - - // Never call because not including all - PowerMockito.verifyPrivate(vitessResultSet, VerificationModeFactory.times(0)) - .invoke("convertBytesIfPossible", Matchers.any(byte[].class), - Matchers.any(FieldWithMetadata.class)); - } - - @Test - public void testGetObjectForStringLikeValues() throws Exception { - ByteString.Output value = ByteString.newOutput(); - - String trimmedCharStr = "wasting space"; - String varcharStr = "i have a variable length!"; - String masqueradingBlobStr = "look at me, im a blob"; - String textStr = "an enthralling string of TEXT in some foreign language"; - String jsonStr = "{\"status\": \"ok\"}"; - - int paddedCharColLength = 20; - byte[] trimmedChar = StringUtils.getBytes(trimmedCharStr, "UTF-16"); - byte[] varchar = StringUtils.getBytes(varcharStr, "UTF-8"); - byte[] masqueradingBlob = StringUtils.getBytes(masqueradingBlobStr, "US-ASCII"); - byte[] text = StringUtils.getBytes(textStr, "ISO8859_8"); - byte[] opaqueBinary = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; - byte[] json = StringUtils.getBytes(jsonStr, "UTF-8"); - - value.write(trimmedChar); - value.write(varchar); - value.write(opaqueBinary); - value.write(masqueradingBlob); - value.write(text); - value.write(json); - - Query.QueryResult result = Query.QueryResult.newBuilder() - // This tests CHAR - .addFields(Query.Field.newBuilder().setName("col1").setColumnLength(paddedCharColLength) - .setCharset(/* utf-16 collation index from CharsetMapping */ 54) - .setType(Query.Type.CHAR)) - // This tests VARCHAR - .addFields(Query.Field.newBuilder().setName("col2").setColumnLength(varchar.length) - .setCharset(CharsetMapping.MYSQL_COLLATION_INDEX_utf8).setType(Query.Type.VARCHAR)) - // This tests VARCHAR that is an opaque binary - .addFields(Query.Field.newBuilder().setName("col2").setColumnLength(opaqueBinary.length) - .setCharset(CharsetMapping.MYSQL_COLLATION_INDEX_binary) - .setFlags(Query.MySqlFlag.BINARY_FLAG_VALUE).setType(Query.Type.VARCHAR)) - // This tests LONGVARCHAR - .addFields(Query.Field.newBuilder().setName("col3").setColumnLength(masqueradingBlob.length) - .setCharset(/* us-ascii collation index from CharsetMapping */11) - .setType(Query.Type.BLOB)) - // This tests TEXT, which falls through the default case of the switch - .addFields(Query.Field.newBuilder().setName("col4").setColumnLength(text.length) - .setCharset(/* corresponds to greek, from CharsetMapping */25).setType(Query.Type.TEXT)) - .addFields(Query.Field.newBuilder().setName("col5").setColumnLength(json.length) - .setCharset(CharsetMapping.MYSQL_COLLATION_INDEX_utf8).setType(Query.Type.JSON)) - .addRows(Query.Row.newBuilder().addLengths(trimmedChar.length).addLengths(varchar.length) - .addLengths(opaqueBinary.length).addLengths(masqueradingBlob.length) - .addLengths(text.length).addLengths(json.length).setValues(value.toByteString())) - .build(); - - VitessConnection conn = getVitessConnection(); - VitessResultSet vitessResultSet = PowerMockito - .spy(new VitessResultSet(new SimpleCursor(result), new VitessStatement(conn))); - vitessResultSet.next(); - - assertEquals(trimmedCharStr, vitessResultSet.getObject(1)); - assertEquals(varcharStr, vitessResultSet.getObject(2)); - Assert.assertArrayEquals(opaqueBinary, (byte[]) vitessResultSet.getObject(3)); - assertEquals(masqueradingBlobStr, vitessResultSet.getObject(4)); - assertEquals(textStr, vitessResultSet.getObject(5)); - assertEquals(jsonStr, vitessResultSet.getObject(6)); - - PowerMockito.verifyPrivate(vitessResultSet, VerificationModeFactory.times(6)) - .invoke("convertBytesIfPossible", Matchers.any(byte[].class), - Matchers.any(FieldWithMetadata.class)); - - conn.setIncludedFields(Query.ExecuteOptions.IncludedFields.TYPE_AND_NAME); - vitessResultSet = PowerMockito - .spy(new VitessResultSet(new SimpleCursor(result), new VitessStatement(conn))); - vitessResultSet.next(); - - Assert.assertArrayEquals(trimmedChar, (byte[]) vitessResultSet.getObject(1)); - Assert.assertArrayEquals(varchar, (byte[]) vitessResultSet.getObject(2)); - Assert.assertArrayEquals(opaqueBinary, (byte[]) vitessResultSet.getObject(3)); - Assert.assertArrayEquals(masqueradingBlob, (byte[]) vitessResultSet.getObject(4)); - Assert.assertArrayEquals(text, (byte[]) vitessResultSet.getObject(5)); - Assert.assertArrayEquals(json, (byte[]) vitessResultSet.getObject(6)); - - PowerMockito.verifyPrivate(vitessResultSet, VerificationModeFactory.times(0)) - .invoke("convertBytesIfPossible", Matchers.any(byte[].class), - Matchers.any(FieldWithMetadata.class)); - } - @Test public void testGetClob() throws SQLException { VitessResultSet vitessResultSet = new VitessResultSet(new String[]{"clob"}, diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessStatementTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessStatementTest.java index 3f4bb39a44c..b641cafdefb 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessStatementTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessStatementTest.java @@ -22,15 +22,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; import static org.mockito.Matchers.nullable; -import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.verify; -import static org.powermock.api.mockito.PowerMockito.doReturn; -import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.when; import io.vitess.client.Context; import io.vitess.client.SQLFuture; @@ -52,18 +45,12 @@ import java.util.Map; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; /** * Created by harshit.gangal on 19/01/16. */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({VTGateConnection.class, Vtrpc.RPCError.class}) public class VitessStatementTest { private String sqlSelect = "select 1 from test_table"; @@ -76,7 +63,7 @@ public class VitessStatementTest { @Test public void testGetConnection() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertEquals(mockConn, statement.getConnection()); @@ -84,24 +71,24 @@ public void testGetConnection() throws SQLException { @Test public void testGetResultSet() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertEquals(null, statement.getResultSet()); } @Test public void testExecuteQuery() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockConn.isSimpleExecute()).thenReturn(true); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(true); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); VitessStatement statement = new VitessStatement(mockConn); //Empty Sql Statement @@ -116,13 +103,13 @@ public void testExecuteQuery() throws SQLException { assertEquals(-1, statement.getUpdateCount()); //autocommit is false and not in transaction - when(mockConn.getAutoCommit()).thenReturn(false); - when(mockConn.isInTransaction()).thenReturn(false); + Mockito.when(mockConn.getAutoCommit()).thenReturn(false); + Mockito.when(mockConn.isInTransaction()).thenReturn(false); rs = statement.executeQuery(sqlSelect); assertEquals(-1, statement.getUpdateCount()); //when returned cursor is null - when(mockSqlFutureCursor.checkedGet()).thenReturn(null); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(null); try { statement.executeQuery(sqlSelect); fail("Should have thrown exception for cursor null"); @@ -133,18 +120,18 @@ public void testExecuteQuery() throws SQLException { @Test public void testExecuteQueryWithStreamExecuteType() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn .streamExecute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockCursor); - when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.STREAM); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.STREAM); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); VitessStatement statement = new VitessStatement(mockConn); //Empty Sql Statement @@ -164,13 +151,13 @@ public void testExecuteQueryWithStreamExecuteType() throws SQLException { assertEquals(-1, statement.getUpdateCount()); //select on primary when tx is null and autocommit is false - when(mockConn.getAutoCommit()).thenReturn(false); - when(mockConn.isInTransaction()).thenReturn(false); + Mockito.when(mockConn.getAutoCommit()).thenReturn(false); + Mockito.when(mockConn.isInTransaction()).thenReturn(false); rs = statement.executeQuery(sqlSelect); assertEquals(-1, statement.getUpdateCount()); //when returned cursor is null - when(mockVtGateConn + Mockito.when(mockVtGateConn .streamExecute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(null); try { @@ -191,19 +178,19 @@ public void testExecuteFetchSizeAsStreaming() throws SQLException { private void testExecute(int fetchSize, boolean simpleExecute, boolean shouldRunExecute, boolean shouldRunStreamExecute) throws SQLException { - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); - VitessConnection mockConn = mock(VitessConnection.class); - when(mockConn.isSimpleExecute()).thenReturn(simpleExecute); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(simpleExecute); + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockVtGateConn + Mockito.when(mockVtGateConn .streamExecute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockCursor); @@ -224,17 +211,17 @@ private void testExecute(int fetchSize, boolean simpleExecute, boolean shouldRun @Test public void testExecuteUpdate() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - List fieldList = mock(ArrayList.class); - - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + List fieldList = Mockito.mock(ArrayList.class); + + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); VitessStatement statement = new VitessStatement(mockConn); //executing dml on primary @@ -242,13 +229,13 @@ public void testExecuteUpdate() throws SQLException { assertEquals(0, updateCount); //tx is null & autoCommit is true - when(mockConn.getAutoCommit()).thenReturn(true); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); updateCount = statement.executeUpdate(sqlUpdate); assertEquals(0, updateCount); //cursor fields is not null - when(mockCursor.getFields()).thenReturn(fieldList); - when(fieldList.isEmpty()).thenReturn(false); + Mockito.when(mockCursor.getFields()).thenReturn(fieldList); + Mockito.when(fieldList.isEmpty()).thenReturn(false); try { statement.executeUpdate(sqlSelect); fail("Should have thrown exception for field not null"); @@ -257,7 +244,7 @@ public void testExecuteUpdate() throws SQLException { } //cursor is null - when(mockSqlFutureCursor.checkedGet()).thenReturn(null); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(null); try { statement.executeUpdate(sqlUpdate); fail("Should have thrown exception for cursor null"); @@ -266,7 +253,7 @@ public void testExecuteUpdate() throws SQLException { } //read only - when(mockConn.isReadOnly()).thenReturn(true); + Mockito.when(mockConn.isReadOnly()).thenReturn(true); try { statement.execute("UPDATE SET foo = 1 ON mytable WHERE id = 1"); fail("Should have thrown exception for read only"); @@ -275,7 +262,7 @@ public void testExecuteUpdate() throws SQLException { } //read only - when(mockConn.isReadOnly()).thenReturn(true); + Mockito.when(mockConn.isReadOnly()).thenReturn(true); try { statement.executeBatch(); fail("Should have thrown exception for read only"); @@ -286,27 +273,27 @@ public void testExecuteUpdate() throws SQLException { @Test public void testExecute() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - List mockFieldList = PowerMockito.spy(new ArrayList<>()); - - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + List mockFieldList = Mockito.spy(new ArrayList<>()); + + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockConn.getAutoCommit()).thenReturn(true); - when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); - when(mockConn.isSimpleExecute()).thenReturn(true); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); + Mockito.when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(true); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(mockFieldList); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(mockFieldList); VitessStatement statement = new VitessStatement(mockConn); int fieldSize = 5; - when(mockCursor.getFields()).thenReturn(mockFieldList); - doReturn(fieldSize).when(mockFieldList).size(); - doReturn(false).when(mockFieldList).isEmpty(); + Mockito.when(mockCursor.getFields()).thenReturn(mockFieldList); + Mockito.doReturn(fieldSize).when(mockFieldList).size(); + Mockito.doReturn(false).when(mockFieldList).isEmpty(); boolean hasResultSet = statement.execute(sqlSelect); assertTrue(hasResultSet); @@ -317,15 +304,15 @@ public void testExecute() throws SQLException { assertNotNull(statement.getResultSet()); int mockUpdateCount = 10; - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); - when(mockCursor.getRowsAffected()).thenReturn((long) mockUpdateCount); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockCursor.getRowsAffected()).thenReturn((long) mockUpdateCount); hasResultSet = statement.execute(sqlUpdate); assertFalse(hasResultSet); assertNull(statement.getResultSet()); assertEquals(mockUpdateCount, statement.getUpdateCount()); //cursor is null - when(mockSqlFutureCursor.checkedGet()).thenReturn(null); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(null); try { statement.execute(sqlUpdate); fail("Should have thrown exception for cursor null"); @@ -336,47 +323,47 @@ public void testExecute() throws SQLException { @Test public void testGetUpdateCount() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFuture = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFuture = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFuture); - when(mockSqlFuture.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFuture.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); VitessStatement statement = new VitessStatement(mockConn); - when(mockCursor.getRowsAffected()).thenReturn(10L); + Mockito.when(mockCursor.getRowsAffected()).thenReturn(10L); int updateCount = statement.executeUpdate(sqlUpdate); assertEquals(10L, updateCount); assertEquals(10L, statement.getUpdateCount()); // Truncated Update Count - when(mockCursor.getRowsAffected()).thenReturn((long) Integer.MAX_VALUE + 10); + Mockito.when(mockCursor.getRowsAffected()).thenReturn((long) Integer.MAX_VALUE + 10); updateCount = statement.executeUpdate(sqlUpdate); assertEquals(Integer.MAX_VALUE, updateCount); assertEquals(Integer.MAX_VALUE, statement.getUpdateCount()); - when(mockConn.isSimpleExecute()).thenReturn(true); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(true); statement.executeQuery(sqlSelect); assertEquals(-1, statement.getUpdateCount()); } @Test public void testClose() throws Exception { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); - when(mockConn.isSimpleExecute()).thenReturn(true); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockConn.getExecuteType()).thenReturn(Constants.QueryExecuteType.SIMPLE); + Mockito.when(mockConn.isSimpleExecute()).thenReturn(true); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); VitessStatement statement = new VitessStatement(mockConn); ResultSet rs = statement.executeQuery(sqlSelect); @@ -391,7 +378,7 @@ public void testClose() throws Exception { @Test public void testGetMaxFieldSize() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertEquals(65535, statement.getMaxFieldSize()); @@ -399,7 +386,7 @@ public void testGetMaxFieldSize() throws SQLException { @Test public void testGetMaxRows() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); @@ -417,7 +404,7 @@ public void testGetMaxRows() throws SQLException { @Test public void testGetQueryTimeout() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); Mockito.when(mockConn.getTimeout()).thenReturn((long) Constants.DEFAULT_TIMEOUT); VitessStatement statement = new VitessStatement(mockConn); @@ -426,7 +413,7 @@ public void testGetQueryTimeout() throws SQLException { @Test public void testGetQueryTimeoutZeroDefault() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); Mockito.when(mockConn.getTimeout()).thenReturn(0L); VitessStatement statement = new VitessStatement(mockConn); @@ -435,7 +422,7 @@ public void testGetQueryTimeoutZeroDefault() throws SQLException { @Test public void testSetQueryTimeout() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); Mockito.when(mockConn.getTimeout()).thenReturn((long) Constants.DEFAULT_TIMEOUT); VitessStatement statement = new VitessStatement(mockConn); @@ -457,7 +444,7 @@ public void testSetQueryTimeout() throws SQLException { @Test public void testGetWarnings() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertNull(statement.getWarnings()); @@ -465,7 +452,7 @@ public void testGetWarnings() throws SQLException { @Test public void testGetFetchDirection() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertEquals(ResultSet.FETCH_FORWARD, statement.getFetchDirection()); @@ -473,7 +460,7 @@ public void testGetFetchDirection() throws SQLException { @Test public void testGetFetchSize() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertEquals(0, statement.getFetchSize()); @@ -481,7 +468,7 @@ public void testGetFetchSize() throws SQLException { @Test public void testGetResultSetConcurrency() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertEquals(ResultSet.CONCUR_READ_ONLY, statement.getResultSetConcurrency()); @@ -489,7 +476,7 @@ public void testGetResultSetConcurrency() throws SQLException { @Test public void testGetResultSetType() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertEquals(ResultSet.TYPE_FORWARD_ONLY, statement.getResultSetType()); @@ -497,7 +484,7 @@ public void testGetResultSetType() throws SQLException { @Test public void testIsClosed() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); assertFalse(statement.isClosed()); @@ -507,23 +494,23 @@ public void testIsClosed() throws SQLException { @Test public void testAutoGeneratedKeys() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockVtGateConn.execute(nullable(Context.class), nullable(String.class), nullable(Map.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); VitessStatement statement = new VitessStatement(mockConn); long expectedFirstGeneratedId = 121; long[] expectedGeneratedIds = {121, 122, 123, 124, 125}; int expectedAffectedRows = 5; - when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); - when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedAffectedRows)); + Mockito.when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); + Mockito.when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedAffectedRows)); //Executing Insert Statement int updateCount = statement.executeUpdate(sqlInsert, Statement.RETURN_GENERATED_KEYS); @@ -550,7 +537,7 @@ public void testAutoGeneratedKeys() throws SQLException { //Fetching Generated Keys on update query expectedFirstGeneratedId = 0; - when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); + Mockito.when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); updateCount = statement.executeUpdate(sqlUpdate, Statement.RETURN_GENERATED_KEYS); assertEquals(expectedAffectedRows, updateCount); @@ -560,7 +547,7 @@ public void testAutoGeneratedKeys() throws SQLException { @Test public void testAddBatch() throws Exception { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); statement.addBatch(sqlInsert); Field privateStringField = VitessStatement.class.getDeclaredField("batchedArgs"); @@ -570,7 +557,7 @@ public void testAddBatch() throws Exception { @Test public void testClearBatch() throws Exception { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); statement.addBatch(sqlInsert); statement.clearBatch(); @@ -581,36 +568,36 @@ public void testClearBatch() throws Exception { @Test public void testExecuteBatch() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); int[] updateCounts = statement.executeBatch(); assertEquals(0, updateCounts.length); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockConn.getAutoCommit()).thenReturn(true); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); - when( + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); + Mockito.when( mockVtGateConn.executeBatch(nullable(Context.class), nullable(List.class), nullable(List.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); List mockCursorWithErrorList = new ArrayList<>(); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); - CursorWithError mockCursorWithError1 = mock(CursorWithError.class); - when(mockCursorWithError1.getError()).thenReturn(null); - when(mockCursorWithError1.getCursor()).thenReturn(mock(Cursor.class)); + CursorWithError mockCursorWithError1 = Mockito.mock(CursorWithError.class); + Mockito.when(mockCursorWithError1.getError()).thenReturn(null); + Mockito.when(mockCursorWithError1.getCursor()).thenReturn(Mockito.mock(Cursor.class)); mockCursorWithErrorList.add(mockCursorWithError1); statement.addBatch(sqlUpdate); updateCounts = statement.executeBatch(); assertEquals(1, updateCounts.length); - CursorWithError mockCursorWithError2 = mock(CursorWithError.class); + CursorWithError mockCursorWithError2 = Mockito.mock(CursorWithError.class); Vtrpc.RPCError rpcError = Vtrpc.RPCError.newBuilder() .setMessage("statement execute batch error").build(); - when(mockCursorWithError2.getError()).thenReturn(rpcError); + Mockito.when(mockCursorWithError2.getError()).thenReturn(rpcError); mockCursorWithErrorList.add(mockCursorWithError2); statement.addBatch(sqlUpdate); statement.addBatch(sqlUpdate); @@ -627,33 +614,33 @@ public void testExecuteBatch() throws SQLException { @Test public void testBatchGeneratedKeys() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockConn.getAutoCommit()).thenReturn(true); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); - when( + Mockito.when( mockVtGateConn.executeBatch(nullable(Context.class), nullable(List.class), nullable(List.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); List mockCursorWithErrorList = new ArrayList<>(); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); - CursorWithError mockCursorWithError = mock(CursorWithError.class); - when(mockCursorWithError.getError()).thenReturn(null); - when(mockCursorWithError.getCursor()).thenReturn(mockCursor); + CursorWithError mockCursorWithError = Mockito.mock(CursorWithError.class); + Mockito.when(mockCursorWithError.getError()).thenReturn(null); + Mockito.when(mockCursorWithError.getCursor()).thenReturn(mockCursor); mockCursorWithErrorList.add(mockCursorWithError); long expectedFirstGeneratedId = 121; long[] expectedGeneratedIds = {121, 122, 123, 124, 125}; - when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); - when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedGeneratedIds.length)); + Mockito.when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); + Mockito.when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedGeneratedIds.length)); statement.addBatch(sqlInsert); statement.executeBatch(); @@ -668,33 +655,33 @@ public void testBatchGeneratedKeys() throws SQLException { @Test public void testBatchUpsertGeneratedKeys() throws SQLException { - VitessConnection mockConn = mock(VitessConnection.class); + VitessConnection mockConn = Mockito.mock(VitessConnection.class); VitessStatement statement = new VitessStatement(mockConn); - Cursor mockCursor = mock(Cursor.class); - SQLFuture mockSqlFutureCursor = mock(SQLFuture.class); + Cursor mockCursor = Mockito.mock(Cursor.class); + SQLFuture mockSqlFutureCursor = Mockito.mock(SQLFuture.class); - VTGateConnection mockVtGateConn = mock(VTGateConnection.class); - when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); - when(mockConn.getAutoCommit()).thenReturn(true); + VTGateConnection mockVtGateConn = Mockito.mock(VTGateConnection.class); + Mockito.when(mockConn.getVtGateConn()).thenReturn(mockVtGateConn); + Mockito.when(mockConn.getAutoCommit()).thenReturn(true); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); - when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursor); + Mockito.when(mockCursor.getFields()).thenReturn(Query.QueryResult.getDefaultInstance().getFieldsList()); - when( + Mockito.when( mockVtGateConn.executeBatch(nullable(Context.class), nullable(List.class), nullable(List.class), nullable(VTSession.class))) .thenReturn(mockSqlFutureCursor); List mockCursorWithErrorList = new ArrayList<>(); - when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); + Mockito.when(mockSqlFutureCursor.checkedGet()).thenReturn(mockCursorWithErrorList); - CursorWithError mockCursorWithError = mock(CursorWithError.class); - when(mockCursorWithError.getError()).thenReturn(null); - when(mockCursorWithError.getCursor()).thenReturn(mockCursor); + CursorWithError mockCursorWithError = Mockito.mock(CursorWithError.class); + Mockito.when(mockCursorWithError.getError()).thenReturn(null); + Mockito.when(mockCursorWithError.getCursor()).thenReturn(mockCursor); mockCursorWithErrorList.add(mockCursorWithError); long expectedFirstGeneratedId = 121; long[] expectedGeneratedIds = {121, 122}; - when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); - when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedGeneratedIds.length)); + Mockito.when(mockCursor.getInsertId()).thenReturn(expectedFirstGeneratedId); + Mockito.when(mockCursor.getRowsAffected()).thenReturn(Long.valueOf(expectedGeneratedIds.length)); statement.addBatch(sqlUpsert); statement.executeBatch(); @@ -709,8 +696,8 @@ public void testBatchUpsertGeneratedKeys() throws SQLException { } VitessStatement noUpdate = new VitessStatement(mockConn); - when(mockCursor.getInsertId()).thenReturn(0L); - when(mockCursor.getRowsAffected()).thenReturn(1L); + Mockito.when(mockCursor.getInsertId()).thenReturn(0L); + Mockito.when(mockCursor.getRowsAffected()).thenReturn(1L); noUpdate.addBatch(sqlUpsert); noUpdate.executeBatch(); diff --git a/java/pom.xml b/java/pom.xml index 6742258a6b8..bc173282faf 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -72,8 +72,8 @@ 4.1.110.Final 2.0.65.Final - 4.28.3 - 3.24.3 + 3.25.5 + 3.25.5 3.0.0 2.24.1 @@ -252,7 +252,7 @@ true true - mysql:mysql-connector-java + com.mysql:mysql-connector-j io.grpc:grpc-context diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index e1df792776b..3d55de7ea14 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -333,8 +333,17 @@ message RowChange { } query.Row before = 1; query.Row after = 2; - // DataColumns is a bitmap of all columns: bit is set if column is present in the after image + // DataColumns is a bitmap of all columns: bit is set if column is + // present in the after image. Bitmap data_columns = 3; + // JsonPartialValues is a bitmap of any JSON columns, where the bit + // is set if the value in the AFTER image is a partial JSON value + // that is represented as an expression of + // JSON_[INSERT|REPLACE|REMOVE](%s, '$.path', value) which then is + // used to add/update/remove a path in the JSON document. When the + // value is used the fmt directive must be replaced by the actual + // column name of the JSON field. + Bitmap json_partial_values = 4; } // RowEvent represent row events for one table. diff --git a/proto/query.proto b/proto/query.proto index c5f53ea6e5d..6c088566fc1 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -219,7 +219,11 @@ enum Type { // Properties: 35, IsQuoted. VECTOR = 2083; // RAW specifies a type which won't be quoted but the value used as-is while encoding. + // Properties: 36, None. RAW = 2084; + // ROW_TUPLE represents multiple rows. + // Properties: 37, None. + ROW_TUPLE = 2085; } // Value represents a typed value. @@ -363,6 +367,12 @@ message ExecuteOptions { oneof timeout { int64 authoritative_timeout = 17; } + + // fetch_last_insert_id indicates that after executing a DML involving last_insert_id(x), + // a subsequent "SELECT last_insert_id()" should be performed to retrieve the updated value. + // This is to circumvent a bug where setting last_insert_id(x) to zero is not signaled by mysql + // https://bugs.mysql.com/bug.php?id=116939 + bool fetch_last_insert_id = 18; } // Field describes a single column returned by a query @@ -427,6 +437,7 @@ message QueryResult { repeated Row rows = 4; string info = 6; string session_state_changes = 7; + bool insert_id_changed=8; } // QueryWarning is used to convey out of band query execution warnings diff --git a/proto/replicationdata.proto b/proto/replicationdata.proto index 76ca3e02103..eba4d323ee6 100644 --- a/proto/replicationdata.proto +++ b/proto/replicationdata.proto @@ -66,7 +66,6 @@ message Configuration { message StopReplicationStatus { replicationdata.Status before = 1; replicationdata.Status after = 2; - bool backup_running = 3; } // StopReplicationMode is used to provide controls over how replication is stopped. @@ -106,4 +105,5 @@ message FullStatus { uint32 semi_sync_wait_for_replica_count = 20; bool super_read_only = 21; replicationdata.Configuration replication_configuration = 22; + bool disk_stalled = 23; } diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto index cf3189db45c..cda173ac044 100644 --- a/proto/tabletmanagerdata.proto +++ b/proto/tabletmanagerdata.proto @@ -360,7 +360,6 @@ message ReplicationStatusRequest { message ReplicationStatusResponse { replicationdata.Status status = 1; - bool backup_running = 2; } message PrimaryStatusRequest { @@ -549,7 +548,6 @@ message StopReplicationAndGetStatusResponse { // Status represents the replication status call right before, and right after telling the replica to stop. replicationdata.StopReplicationStatus status = 2; - bool backup_running = 3; } message PromoteReplicaRequest { @@ -762,6 +760,13 @@ message VDiffOptions { VDiffReportOptions report_options = 3; } +message VDiffTableLastPK { + query.QueryResult target = 1; + // If the source value is nil then it's the same as the target + // and the target value should be used for both. + optional query.QueryResult source = 2; +} + // UpdateVReplicationWorkflowRequest is used to update an existing VReplication // workflow. Note that the following fields MUST have an explicit value provided @@ -776,8 +781,9 @@ message UpdateVReplicationWorkflowRequest { optional TabletSelectionPreference tablet_selection_preference = 4; optional binlogdata.OnDDLAction on_ddl = 5; optional binlogdata.VReplicationWorkflowState state = 6; - reserved 7; // unused, was: repeated string shards + repeated string shards = 7; map config_overrides = 8; + optional string message = 9; } message UpdateVReplicationWorkflowResponse { diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index b1e5fb215bc..745a3599cc9 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -556,6 +556,20 @@ message CompleteSchemaMigrationResponse { map rows_affected_by_shard = 1; } +message CopySchemaShardRequest { + topodata.TabletAlias source_tablet_alias = 1; + repeated string tables = 2; + repeated string exclude_tables = 3; + bool include_views = 4; + bool skip_verify = 5; + vttime.Duration wait_replicas_timeout = 6; + string destination_keyspace = 7; + string destination_shard = 8; +} + +message CopySchemaShardResponse { +} + message CreateKeyspaceRequest { // Name is the name of the keyspace. string name = 1; @@ -1217,6 +1231,18 @@ message LaunchSchemaMigrationResponse { map rows_affected_by_shard = 1; } +message LookupVindexCompleteRequest { + // Where the lookup vindex lives. + string keyspace = 1; + // This is the name of the lookup vindex and the vreplication workflow. + string name = 2; + // Where the vreplication workflow lives. + string table_keyspace = 3; +} + +message LookupVindexCompleteResponse { +} + message LookupVindexCreateRequest { string keyspace = 1; string workflow = 2; @@ -1237,11 +1263,28 @@ message LookupVindexExternalizeRequest { string name = 2; // Where the vreplication workflow lives. string table_keyspace = 3; + // If this is set true, we directly delete the workflow instead of stopping. + // Also, complete command is not required to delete workflow in that case. + bool delete_workflow = 4; } message LookupVindexExternalizeResponse { - // Was the workflow also deleted. - bool workflow_deleted = 1; + // Was the workflow stopped. + bool workflow_stopped = 1; + // Was the workflow deleted. + bool workflow_deleted = 2; +} + +message LookupVindexInternalizeRequest { + // Where the lookup vindex lives. + string keyspace = 1; + // This is the name of the lookup vindex and the vreplication workflow. + string name = 2; + // Where the vreplication workflow lives. + string table_keyspace = 3; +} + +message LookupVindexInternalizeResponse { } message MaterializeCreateRequest { @@ -1860,12 +1903,25 @@ message ValidateKeyspaceResponse { map results_by_shard = 2; } +message ValidatePermissionsKeyspaceRequest { + string keyspace = 1; + // If you only want to validate a subset of the shards in the + // keyspace, then specify a list of shard names. + repeated string shards = 2; +} + +message ValidatePermissionsKeyspaceResponse { +} + message ValidateSchemaKeyspaceRequest { string keyspace = 1; repeated string exclude_tables = 2; bool include_views = 3; bool skip_no_primary = 4; bool include_vschema = 5; + // If you only want to validate a subset of the shards in the + // keyspace, then specify a list of shard names. + repeated string shards = 6; } message ValidateSchemaKeyspaceResponse { diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 3133d4fb4e1..1f07de4c523 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -74,6 +74,8 @@ service Vtctld { rpc CompleteSchemaMigration(vtctldata.CompleteSchemaMigrationRequest) returns (vtctldata.CompleteSchemaMigrationResponse) {}; // CompleteSchemaMigration completes one or all migrations executed with --postpone-completion. rpc ConcludeTransaction(vtctldata.ConcludeTransactionRequest) returns (vtctldata.ConcludeTransactionResponse) {}; + // CopySchemaShard copies the schema from a source tablet to all tablets in a keyspace/shard. + rpc CopySchemaShard(vtctldata.CopySchemaShardRequest) returns (vtctldata.CopySchemaShardResponse) {}; // CreateKeyspace creates the specified keyspace in the topology. For a // SNAPSHOT keyspace, the request must specify the name of a base keyspace, // as well as a snapshot time. @@ -193,8 +195,10 @@ service Vtctld { // LaunchSchemaMigration launches one or all migrations executed with --postpone-launch. rpc LaunchSchemaMigration(vtctldata.LaunchSchemaMigrationRequest) returns (vtctldata.LaunchSchemaMigrationResponse) {}; + rpc LookupVindexComplete(vtctldata.LookupVindexCompleteRequest) returns (vtctldata.LookupVindexCompleteResponse) {}; rpc LookupVindexCreate(vtctldata.LookupVindexCreateRequest) returns (vtctldata.LookupVindexCreateResponse) {}; rpc LookupVindexExternalize(vtctldata.LookupVindexExternalizeRequest) returns (vtctldata.LookupVindexExternalizeResponse) {}; + rpc LookupVindexInternalize(vtctldata.LookupVindexInternalizeRequest) returns (vtctldata.LookupVindexInternalizeResponse) {}; // MaterializeCreate creates a workflow to materialize one or more tables // from a source keyspace to a target keyspace using a provided expressions. @@ -349,6 +353,8 @@ service Vtctld { // ValidateKeyspace validates that all nodes reachable from the specified // keyspace are consistent. rpc ValidateKeyspace(vtctldata.ValidateKeyspaceRequest) returns (vtctldata.ValidateKeyspaceResponse) {}; + // ValidatePermissionsKeyspace validates that all the permissions are the same in a keyspace. + rpc ValidatePermissionsKeyspace(vtctldata.ValidatePermissionsKeyspaceRequest) returns (vtctldata.ValidatePermissionsKeyspaceResponse) {}; // ValidateSchemaKeyspace validates that the schema on the primary tablet for shard 0 matches the schema on all of the other tablets in the keyspace. rpc ValidateSchemaKeyspace(vtctldata.ValidateSchemaKeyspaceRequest) returns (vtctldata.ValidateSchemaKeyspaceResponse) {}; // ValidateShard validates that all nodes reachable from the specified shard diff --git a/test.go b/test.go index 95d62af892f..247541009a6 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", "39", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "41", "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") @@ -112,7 +112,7 @@ const ( configFileName = "test/config.json" // List of flavors for which a bootstrap Docker image is available. - flavors = "mysql80,percona80" + flavors = "mysql80,mysql84,percona80" ) // Config is the overall object serialized in test/config.json. diff --git a/test/bin/.keep b/test/bin/.keep new file mode 100644 index 00000000000..7f6eda3a448 --- /dev/null +++ b/test/bin/.keep @@ -0,0 +1 @@ +Do not remove. Ensures existence of directory. diff --git a/test/bin/rippled b/test/bin/rippled deleted file mode 100755 index c7b6bea3b95..00000000000 Binary files a/test/bin/rippled and /dev/null differ diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index 7956c491408..bf42825d73c 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -103,6 +103,7 @@ var ( "vtgate_vindex_heavy", "vtgate_vschema", "vtgate_queries", + "vtgate_plantests", "vtgate_schema_tracker", "vtgate_foreignkey_stress", "vtorc", @@ -157,6 +158,9 @@ var ( "vreplication_migrate", "vreplication_vtctldclient_vdiff2_movetables_tz", } + clusterRequiringMinio = []string{ + "21", + } ) type unitTest struct { @@ -172,8 +176,10 @@ type clusterTest struct { Docker bool LimitResourceUsage bool EnableBinlogTransactionCompression bool + EnablePartialJSON bool PartialKeyspace bool Cores16 bool + NeedsMinio bool } type vitessTesterTest struct { @@ -286,6 +292,13 @@ func generateClusterWorkflows(list []string, tpl string) { break } } + minioClusters := canonnizeList(clusterRequiringMinio) + for _, minioCluster := range minioClusters { + if minioCluster == cluster { + test.NeedsMinio = true + break + } + } if mysqlVersion == mysql57 { test.Platform = string(mysql57) } @@ -294,6 +307,7 @@ func generateClusterWorkflows(list []string, tpl string) { } if strings.Contains(cluster, "vrepl") { test.EnableBinlogTransactionCompression = true + test.EnablePartialJSON = true } mysqlVersionIndicator := "" if mysqlVersion != defaultMySQLVersion && len(clusterMySQLVersions()) > 1 { diff --git a/test/config.json b/test/config.json index 1e278546c7a..17cdb019e97 100644 --- a/test/config.json +++ b/test/config.json @@ -8,7 +8,7 @@ "java_test" ], "Manual": false, - "Shard": "10", + "Shard": "java", "RetryMax": 1, "Tags": [] }, @@ -19,7 +19,7 @@ "test/client_test.sh" ], "Manual": false, - "Shard": "25", + "Shard": "java", "RetryMax": 1, "Tags": [] }, @@ -136,6 +136,15 @@ "RetryMax": 1, "Tags": [] }, + "backup_s3": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/backup/s3", "-timeout", "30m"], + "Command": [], + "Manual": false, + "Shard": "21", + "RetryMax": 1, + "Tags": [] + }, "backup_only": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/backup/vtbackup", "-timeout", "20m"], @@ -340,17 +349,6 @@ "RetryMax": 1, "Tags": [] }, - "pitr": { - "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/recovery/pitr"], - "Command": [], - "Manual": false, - "Shard": "10", - "RetryMax": 1, - "Tags": [ - "site_test" - ] - }, "recovery": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/recovery/unshardedrecovery"], @@ -485,7 +483,7 @@ ], "Command": [], "Manual": false, - "Shard": "25", + "Shard": "docker_cluster", "RetryMax": 1, "Tags": [ "site_test" @@ -606,7 +604,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_queries_subquery": { "File": "unused.go", @@ -615,7 +613,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_queries_union": { "File": "unused.go", @@ -624,7 +622,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_queries_insert": { "File": "unused.go", @@ -633,7 +631,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_queries_vexplain": { "File": "unused.go", @@ -642,7 +640,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_queries_reference": { "File": "unused.go", @@ -651,7 +649,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_queries_random": { "File": "unused.go", @@ -660,7 +658,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_kill": { "File": "unused.go", @@ -669,7 +667,7 @@ "Manual": false, "Shard": "vtgate_queries", "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": ["upgrade_downgrade_query_serving_queries_2"] }, "vtgate_concurrentdml": { "File": "unused.go", @@ -887,6 +885,15 @@ "RetryMax": 1, "Tags": [] }, + "vtgate_plantests": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/plan_tests"], + "Command": [], + "Manual": false, + "Shard": "vtgate_plantests", + "RetryMax": 1, + "Tags": [] + }, "vtgate_unsharded": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/unsharded"], @@ -982,7 +989,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2", "--topo-flavor=zk2"], "Command": [], "Manual": false, - "Shard": "25", + "Shard": "docker_cluster", "RetryMax": 1, "Tags": [] }, @@ -1054,7 +1061,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtcombo"], "Command": [], "Manual": false, - "Shard": "25", + "Shard": "docker_cluster", "RetryMax": 1, "Tags": [] }, @@ -1303,6 +1310,15 @@ "RetryMax": 1, "Tags": [] }, + "global_routing": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestGlobalRouting", "-timeout", "30m"], + "Command": [], + "Manual": false, + "Shard": "vreplication_v2", + "RetryMax": 1, + "Tags": [] + }, "vreplication_fk": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestFKWorkflow"], @@ -1339,18 +1355,9 @@ "RetryMax": 1, "Tags": [] }, - "vreplication_vtctl_migrate": { + "vreplication_migrate": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVtctlMigrate", "-timeout", "30m"], - "Command": [], - "Manual": false, - "Shard": "vreplication_migrate", - "RetryMax": 1, - "Tags": [] - }, - "vreplication_vtctld_migrate": { - "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVtctldMigrate", "-timeout", "30m"], + "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMigrate", "-timeout", "30m"], "Command": [], "Manual": false, "Shard": "vreplication_migrate", @@ -1384,6 +1391,15 @@ "RetryMax": 1, "Tags": [] }, + "loopkup_index": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestLookupIndex"], + "Command": [], + "Manual": false, + "Shard": "vreplication_vtctldclient_vdiff2_movetables_tz", + "RetryMax": 1, + "Tags": [] + }, "vtadmin": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtadmin"], diff --git a/test/local_example.sh b/test/local_example.sh index 391e75a9224..27f512a34eb 100755 --- a/test/local_example.sh +++ b/test/local_example.sh @@ -98,5 +98,11 @@ mysql --table < ../common/select_customer80-_data.sql ./306_down_shard_0.sh -./401_teardown.sh +./401_backup.sh + +./402_list_backup.sh + +./403_restore_from_backup.sh + +./501_teardown.sh diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index 6fe58fae361..c5129805126 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -13,6 +13,7 @@ env: jobs: build: + timeout-minutes: 60 name: Run endtoend tests on {{.Name}} runs-on: {{if .Cores16}}gh-hosted-runners-16cores-1-24.04{{else}}ubuntu-24.04{{end}} @@ -56,7 +57,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -66,6 +69,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' @@ -105,6 +109,7 @@ jobs: - name: Get dependencies if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 run: | {{if .InstallXtraBackup}} @@ -157,6 +162,15 @@ jobs: {{end}} + {{if .NeedsMinio }} + - name: Install Minio + if: steps.skip-workflow.outputs.skip-workflow == 'false' + run: | + wget https://dl.min.io/server/minio/release/linux-amd64/minio + chmod +x minio + mv minio /usr/local/bin + {{end}} + {{if .MakeTools}} - name: Installing zookeeper and consul @@ -215,6 +229,12 @@ jobs: EOF {{end}} + {{if .EnablePartialJSON}} + cat <<-EOF>>./config/mycnf/mysql8026.cnf + binlog-row-value-options=PARTIAL_JSON + EOF + {{end}} + # run the tests however you normally do, then produce a JUnit XML file eatmydata -- go run test.go -docker={{if .Docker}}true -flavor={{.Platform}}{{else}}false{{end}} -follow -shard {{.Shard}}{{if .PartialKeyspace}} -partial-keyspace=true {{end}}{{if .BuildTag}} -build-tag={{.BuildTag}} {{end}} | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/test/templates/cluster_endtoend_test_docker.tpl b/test/templates/cluster_endtoend_test_docker.tpl index f7e8aa2c1d8..39a36b88c89 100644 --- a/test/templates/cluster_endtoend_test_docker.tpl +++ b/test/templates/cluster_endtoend_test_docker.tpl @@ -28,7 +28,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -38,6 +40,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' diff --git a/test/templates/cluster_endtoend_test_mysql57.tpl b/test/templates/cluster_endtoend_test_mysql57.tpl index f4152c939b0..a6cbc969c1a 100644 --- a/test/templates/cluster_endtoend_test_mysql57.tpl +++ b/test/templates/cluster_endtoend_test_mysql57.tpl @@ -61,7 +61,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -71,6 +73,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/onlineddl/vrepl_suite/**' diff --git a/test/templates/cluster_vitess_tester.tpl b/test/templates/cluster_vitess_tester.tpl index b8d77754ba6..508824dde87 100644 --- a/test/templates/cluster_vitess_tester.tpl +++ b/test/templates/cluster_vitess_tester.tpl @@ -43,7 +43,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -53,6 +55,7 @@ jobs: token: '' filters: | end_to_end: + - 'test/config.json' - 'go/**/*.go' - 'go/vt/sidecardb/**/*.sql' - 'go/test/endtoend/vtgate/vitess_tester/**' diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl index af4376d3ca9..733377418f8 100644 --- a/test/templates/dockerfile.tpl +++ b/test/templates/dockerfile.tpl @@ -1,4 +1,4 @@ -ARG bootstrap_version=39 +ARG bootstrap_version=41 ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" FROM "${image}" diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 3704aebac4e..10c3b8c0c6a 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -43,7 +43,9 @@ jobs: - name: Check out code if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: 'false' - name: Check for changes in relevant files if: steps.skip-workflow.outputs.skip-workflow == 'false' @@ -53,6 +55,7 @@ jobs: token: '' filters: | unit_tests: + - 'test/config.json' - 'go/**' - 'test.go' - 'Makefile' @@ -177,6 +180,9 @@ jobs: export NOVTADMINBUILD=1 export VTEVALENGINETEST="{{.Evalengine}}" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="{{.Platform}}" eatmydata -- make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/web/vtadmin/README.md b/web/vtadmin/README.md index d6bcd67d277..629fe116711 100644 --- a/web/vtadmin/README.md +++ b/web/vtadmin/README.md @@ -2,8 +2,8 @@ ## Prerequisites -- [node](https://nodejs.org) >= 20.12.0 LTS -- npm >= 10.5.0 (comes with node) +- [node](https://nodejs.org) >= 22.13.1 LTS +- npm >= 10.9.2 (comes with node) ## Available scripts diff --git a/web/vtadmin/build.sh b/web/vtadmin/build.sh index b8481ccdc0e..d253233492f 100755 --- a/web/vtadmin/build.sh +++ b/web/vtadmin/build.sh @@ -40,7 +40,7 @@ if [[ -z ${NVM_DIR} ]]; then fi if [[ -z ${NODE_VERSION} ]]; then - export NODE_VERSION="20.12.2" + export NODE_VERSION="22.13.1" fi output "\nInstalling nvm...\n" diff --git a/web/vtadmin/package-lock.json b/web/vtadmin/package-lock.json index 6004278321a..a6ef94d4da2 100644 --- a/web/vtadmin/package-lock.json +++ b/web/vtadmin/package-lock.json @@ -18,7 +18,6 @@ "d3": "^7.9.0", "dayjs": "^1.11.7", "downshift": "^7.2.0", - "highcharts-react-official": "^3.1.0", "history": "^5.3.0", "lodash-es": "^4.17.21", "path-to-regexp": "^8.1.0", @@ -28,6 +27,7 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-flow-renderer": "^10.3.17", + "react-json-tree": "^0.19.0", "react-query": "^3.5.9", "react-router-dom": "^5.3.4", "react-tiny-popover": "^6.0.5", @@ -37,7 +37,7 @@ "web-vitals": "^3.1.1" }, "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.1", + "@rollup/plugin-commonjs": "^28.0.2", "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.5", "@testing-library/react-hooks": "^5.0.3", @@ -53,37 +53,39 @@ "i": "^0.3.7", "jsdom": "^21.1.1", "msw": "^2.5.2", - "npm": "^10.8.0", + "npm": "^10.9.2", "postcss": "^8.4.31", "prettier": "^2.2.1", - "protobufjs-cli": "^1.1.1", + "protobufjs-cli": "^1.1.3", "serve": "^14.2.0", "stylelint": "^14.4.0", "stylelint-config-prettier": "^9.0.3", "stylelint-config-standard-scss": "^3.0.0", "tailwindcss": "^3.0.18", "typescript": "^5.0.2", - "vite": "^4.5.3", + "vite": "^4.5.6", "vite-plugin-eslint": "^1.8.1", "vite-plugin-svgr": "^2.4.0", "vitest": "^0.29.8" }, "engines": { - "node": ">=20.12.0", - "npm": ">=10.5.0" + "node": ">=22.13.0", + "npm": ">=10.9.2" } }, "node_modules/@adobe/css-tools": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", - "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==", - "dev": true + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "dev": true, + "license": "MIT" }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -96,6 +98,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -105,11 +108,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -117,30 +122,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", - "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", + "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", - "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.24.5", - "@babel/helpers": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.5", - "@babel/types": "^7.24.5", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -156,10 +163,11 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.5.tgz", - "integrity": "sha512-gsUcqS/fPlgAw1kOtpss7uhY6E9SFFANQ6EFX5GTvzUwaV0+sGaZWk6xq22MOdeT9wfxyokW3ceCUvOiRtZciQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.26.5.tgz", + "integrity": "sha512-Kkm8C8uxI842AwQADxl0GbcG1rupELYLShazYEZO/2DYjhyWXJIOUVOE3tBYm6JXzUCNJOZEzqc4rCW/jsEQYQ==", "dev": true, + "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", @@ -178,58 +186,51 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/@babel/generator": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", - "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.5", + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -238,19 +239,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", - "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.24.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -261,13 +261,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -278,10 +279,11 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -293,75 +295,44 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", - "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.0" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", - "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-simple-access": "^7.24.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/helper-validator-identifier": "^7.24.5" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -371,35 +342,38 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz", - "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -409,14 +383,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -425,194 +400,119 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", - "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", - "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", - "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz", - "integrity": "sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.23.0", - "@babel/template": "^7.24.0", - "@babel/types": "^7.24.5" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz", - "integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.5", - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", - "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@babel/parser": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", + "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", + "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "@babel/types": "^7.26.5" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", - "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" + "node": ">=6.9.0" }, - "engines": { - "node": ">=6.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz", - "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==", + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -622,12 +522,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", - "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -637,14 +538,15 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", - "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -654,13 +556,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", - "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -675,6 +578,7 @@ "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -687,14 +591,15 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.1.tgz", - "integrity": "sha512-zPEvzFijn+hRvJuX2Vu3KbEBN39LN3f7tW3MQO2LsIs57B26KU+kUc82BdAktS1VCM6libzh45eKGI65lg0cpA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", + "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-decorators": "^7.24.1" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-decorators": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -709,6 +614,7 @@ "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -726,6 +632,7 @@ "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -743,6 +650,7 @@ "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", @@ -761,6 +669,7 @@ "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -777,45 +686,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -824,12 +695,13 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.1.tgz", - "integrity": "sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", + "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -838,37 +710,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz", - "integrity": "sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz", + "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -878,12 +727,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -893,12 +743,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -907,37 +758,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -946,23 +774,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -975,6 +792,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -982,35 +800,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1018,43 +813,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", - "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1068,6 +834,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1080,12 +847,13 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1095,15 +863,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1113,14 +881,15 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1130,12 +899,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", - "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1145,12 +915,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz", - "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1160,13 +931,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1176,14 +948,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", - "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.4", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1193,18 +965,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz", - "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.24.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "engines": { @@ -1215,13 +986,14 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1231,12 +1003,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz", - "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1246,13 +1019,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1262,12 +1036,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1276,14 +1051,31 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", - "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1293,13 +1085,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", - "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1309,13 +1101,13 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", - "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1325,13 +1117,14 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.1.tgz", - "integrity": "sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.26.5.tgz", + "integrity": "sha512-eGK26RsbIkYUns3Y8qKl362juDDYK+wEdPGHGrhzUl6CewZFo55VZ7hg+CyMFU4dd5QQakBN86nBMpRsFpRvbQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-flow": "^7.24.1" + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/plugin-syntax-flow": "^7.26.0" }, "engines": { "node": ">=6.9.0" @@ -1341,13 +1134,14 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1357,14 +1151,15 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1374,13 +1169,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1390,12 +1185,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1405,13 +1201,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", - "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1421,12 +1217,13 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", - "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1436,13 +1233,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1452,14 +1250,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1469,15 +1267,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1487,13 +1286,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1503,13 +1303,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1519,12 +1320,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1534,13 +1336,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", - "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", + "version": "7.26.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1550,13 +1352,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1566,15 +1368,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz", - "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.5" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1584,13 +1386,14 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1600,13 +1403,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", - "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1616,14 +1419,14 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz", - "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1633,12 +1436,13 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz", - "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1648,13 +1452,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1664,15 +1469,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz", - "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1682,12 +1487,13 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1697,12 +1503,13 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz", - "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1712,16 +1519,17 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1731,12 +1539,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" + "@babel/plugin-transform-react-jsx": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1746,12 +1555,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.5.tgz", - "integrity": "sha512-RtCJoUO2oYrYwFPtR1/jkoBEcFuI1ae9a9IMxeyAVa3a1Ap4AnxmyIKG2b2FaJKqkidw/0cxRbWN+HOs6ZWd1w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1761,12 +1571,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.1.tgz", - "integrity": "sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1776,13 +1587,14 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz", - "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1792,12 +1604,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1807,13 +1620,31 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1823,15 +1654,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", - "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, @@ -1843,12 +1675,13 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1858,13 +1691,14 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1874,12 +1708,13 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1889,12 +1724,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1904,12 +1740,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz", - "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1919,15 +1756,17 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz", - "integrity": "sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.5.tgz", + "integrity": "sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-typescript": "^7.24.1" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1937,12 +1776,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1952,13 +1792,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", - "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1968,13 +1809,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1984,13 +1826,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2000,91 +1843,80 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", - "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.5", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.4", - "@babel/plugin-transform-classes": "^7.24.5", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.5", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.5", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.5", - "@babel/plugin-transform-parameters": "^7.24.5", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.5", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.5", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", + "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "engines": { @@ -2099,6 +1931,7 @@ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -2109,17 +1942,18 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz", - "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.26.3.tgz", + "integrity": "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-transform-react-display-name": "^7.24.1", - "@babel/plugin-transform-react-jsx": "^7.23.4", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.24.1" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2129,16 +1963,17 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz", - "integrity": "sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-syntax-jsx": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-typescript": "^7.24.1" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2147,16 +1982,11 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2165,10 +1995,11 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.5.tgz", - "integrity": "sha512-GWO0mgzNMLWaSYM4z4NVIuY0Cd1fl8cPnuetuddu5w/qGuvt5Y7oUi/kvvQGK9xgOkFJDQX2heIvTRn/OQ1XTg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", "dev": true, + "license": "MIT", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -2178,33 +2009,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", - "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/types": "^7.24.5", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz", + "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.5", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.5", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2213,31 +2043,33 @@ } }, "node_modules/@babel/types": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", - "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", + "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.1", - "@babel/helper-validator-identifier": "^7.24.5", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@bugsnag/browser": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@bugsnag/browser/-/browser-7.22.7.tgz", - "integrity": "sha512-70jFkWKscK2osm7bnFbPLevrzHClrygM3UcKetKs/l81Xuzlxnu1SS3onN5OUl9kd9RN4XMFr46Pv5jSqWqImQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@bugsnag/browser/-/browser-7.25.0.tgz", + "integrity": "sha512-PzzWy5d9Ly1CU1KkxTB6ZaOw/dO+CYSfVtqxVJccy832e6+7rW/dvSw5Jy7rsNhgcKSKjZq86LtNkPSvritOLA==", + "license": "MIT", "dependencies": { - "@bugsnag/core": "^7.22.7" + "@bugsnag/core": "^7.25.0" } }, "node_modules/@bugsnag/core": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@bugsnag/core/-/core-7.22.7.tgz", - "integrity": "sha512-9DPWBkkBjhFJc5dCFy/wVC3HE0Aw3ZiLJKjyAxgywSKbILgtpD+qT1Xe8sacWyxU92znamlZ8H8ziQOe7jhhbA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@bugsnag/core/-/core-7.25.0.tgz", + "integrity": "sha512-JZLak1b5BVzy77CPcklViZrppac/pE07L3uSDmfSvFYSCGReXkik2txOgV05VlF9EDe36dtUAIIV7iAPDfFpQQ==", + "license": "MIT", "dependencies": { "@bugsnag/cuid": "^3.0.0", "@bugsnag/safe-json-stringify": "^6.0.0", @@ -2249,23 +2081,26 @@ "node_modules/@bugsnag/cuid": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@bugsnag/cuid/-/cuid-3.1.1.tgz", - "integrity": "sha512-d2z4b0rEo3chI07FNN1Xds8v25CNeekecU6FC/2Fs9MxY2EipkZTThVcV2YinMn8dvRUlViKOyC50evoUxg8tw==" + "integrity": "sha512-d2z4b0rEo3chI07FNN1Xds8v25CNeekecU6FC/2Fs9MxY2EipkZTThVcV2YinMn8dvRUlViKOyC50evoUxg8tw==", + "license": "MIT" }, "node_modules/@bugsnag/js": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@bugsnag/js/-/js-7.22.7.tgz", - "integrity": "sha512-Qq8l06rSDTZtxgNIDpTeXHrin9C30INNbPfnR2CNcEsCmfqyVQb4USPEuRb0xg5wiaLKU9r4IAatMqiCgdzG6A==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@bugsnag/js/-/js-7.25.0.tgz", + "integrity": "sha512-d8n8SyKdRUz8jMacRW1j/Sj/ckhKbIEp49+Dacp3CS8afRgfMZ//NXhUFFXITsDP5cXouaejR9fx4XVapYXNgg==", + "license": "MIT", "dependencies": { - "@bugsnag/browser": "^7.22.7", - "@bugsnag/node": "^7.22.7" + "@bugsnag/browser": "^7.25.0", + "@bugsnag/node": "^7.25.0" } }, "node_modules/@bugsnag/node": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@bugsnag/node/-/node-7.22.7.tgz", - "integrity": "sha512-Ud8vpX9UkGxoWAk7OigyR7w1eycbsE5uv5KZx0aWiqDPXylvICd42V5ZiWstpkdm9IVFo9AQ4+gmerHPe4Lwrg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@bugsnag/node/-/node-7.25.0.tgz", + "integrity": "sha512-KlxBaJ8EREEsfKInybAjTO9LmdDXV3cUH5+XNXyqUZrcRVuPOu4j4xvljh+n24ifok/wbFZTKVXUzrN4iKIeIA==", + "license": "MIT", "dependencies": { - "@bugsnag/core": "^7.22.7", + "@bugsnag/core": "^7.25.0", "byline": "^5.0.0", "error-stack-parser": "^2.0.2", "iserror": "^0.0.2", @@ -2276,7 +2111,8 @@ "node_modules/@bugsnag/safe-json-stringify": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@bugsnag/safe-json-stringify/-/safe-json-stringify-6.0.0.tgz", - "integrity": "sha512-htzFO1Zc57S8kgdRK9mLcPVTW1BY2ijfH7Dk2CeZmspTWKdKqSo1iwmqrq2WtRjFlo8aRZYgLX0wFrDXF/9DLA==" + "integrity": "sha512-htzFO1Zc57S8kgdRK9mLcPVTW1BY2ijfH7Dk2CeZmspTWKdKqSo1iwmqrq2WtRjFlo8aRZYgLX0wFrDXF/9DLA==", + "license": "MIT" }, "node_modules/@bundled-es-modules/cookie": { "version": "2.0.1", @@ -2310,9 +2146,9 @@ } }, "node_modules/@csstools/cascade-layer-name-parser": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.9.tgz", - "integrity": "sha512-RRqNjxTZDUhx7pxYOBG/AkCVmPS3zYzfE47GEhIGkFuWFTQGJBgWOUUkKNo5MfxIfjDz5/1L3F3rF1oIsYaIpw==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.13.tgz", + "integrity": "sha512-MX0yLTwtZzr82sQ0zOjqimpZbzjMaK/h2pmlrLK7DCzlmiZLYFpoO94WmN1akRVo6ll/TdpHb53vihHLUMyvng==", "funding": [ { "type": "github", @@ -2323,18 +2159,19 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.6.1", - "@csstools/css-tokenizer": "^2.2.4" + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1" } }, "node_modules/@csstools/color-helpers": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-4.2.0.tgz", - "integrity": "sha512-hJJrSBzbfGxUsaR6X4Bzd/FLx0F1ulKnR5ljY9AiXCtsR+H+zSWQDFWlKES1BRaVZTDHLpIIHS9K2o0h+JLlrg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-4.2.1.tgz", + "integrity": "sha512-CEypeeykO9AN7JWkr1OEOQb0HRzZlPWGwV0Ya6DuVgFdDi6g3ma/cPZ5ZPZM4AWQikDpq/0llnGGlIL+j8afzw==", "funding": [ { "type": "github", @@ -2345,14 +2182,15 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT-0", "engines": { "node": "^14 || ^16 || >=18" } }, "node_modules/@csstools/css-calc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-1.2.0.tgz", - "integrity": "sha512-iQqIW5vDPqQdLx07/atCuNKDprhIWjB0b8XRhUyXZWBZYUG+9mNyFwyu30rypX84WLevVo25NYW2ipxR8WyseQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-1.2.4.tgz", + "integrity": "sha512-tfOuvUQeo7Hz+FcuOd3LfXVp+342pnWUJ7D2y8NUpu1Ww6xnTbHLpz018/y6rtbHifJ3iIEf9ttxXd8KG7nL0Q==", "funding": [ { "type": "github", @@ -2363,12 +2201,13 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.6.1", - "@csstools/css-tokenizer": "^2.2.4" + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1" } }, "node_modules/@csstools/css-color-parser": { @@ -2385,6 +2224,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { "@csstools/color-helpers": "^4.1.0", "@csstools/css-calc": "^1.2.0" @@ -2398,9 +2238,9 @@ } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.1.tgz", - "integrity": "sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", + "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", "funding": [ { "type": "github", @@ -2411,17 +2251,18 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" }, "peerDependencies": { - "@csstools/css-tokenizer": "^2.2.4" + "@csstools/css-tokenizer": "^2.4.1" } }, "node_modules/@csstools/css-tokenizer": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.4.tgz", - "integrity": "sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", + "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", "funding": [ { "type": "github", @@ -2432,14 +2273,15 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" } }, "node_modules/@csstools/media-query-list-parser": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.9.tgz", - "integrity": "sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==", + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", + "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", "funding": [ { "type": "github", @@ -2450,18 +2292,20 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.6.1", - "@csstools/css-tokenizer": "^2.2.4" + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1" } }, "node_modules/@csstools/postcss-cascade-layers": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-3.0.1.tgz", "integrity": "sha512-dD8W98dOYNOH/yX4V4HXOhfCOnvVAg8TtsL+qCGNoKXuq5z2C/d026wGWgySgC8cajXXo/wNezS31Glj5GcqrA==", + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" @@ -2491,6 +2335,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2518,6 +2363,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2535,6 +2381,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-2.0.2.tgz", "integrity": "sha512-iKYZlIs6JsNT7NKyRjyIyezTCHLh4L4BBB3F5Nx7Dc4Z/QmBgX+YJFuUSar8IM6KclGiAUFGomXFdYxAwJydlA==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2563,6 +2410,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2590,6 +2438,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2616,6 +2465,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" @@ -2641,6 +2491,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -2656,6 +2507,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-1.0.1.tgz", "integrity": "sha512-eO9z2sMLddvlfFEW5Fxbjyd03zaO7cJafDurK4rCqyRt9P7aaWwha0LcSzoROlcZrw1NBV2JAp2vMKfPMQO1xw==", + "license": "CC0-1.0", "engines": { "node": "^14 || ^16 || >=18" }, @@ -2671,6 +2523,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-1.0.1.tgz", "integrity": "sha512-x1ge74eCSvpBkDDWppl+7FuD2dL68WP+wwP2qvdUcKY17vJksz+XoE1ZRV38uJgS6FNUwC0AxrPW5gy3MxsDHQ==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2689,6 +2542,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-1.0.3.tgz", "integrity": "sha512-6zqcyRg9HSqIHIPMYdt6THWhRmE5/tyHKJQLysn2TeDf/ftq7Em9qwMTx98t2C/7UxIsYS8lOiHHxAVjWn2WUg==", + "license": "CC0-1.0", "dependencies": { "@csstools/css-tokenizer": "^2.1.1" }, @@ -2704,9 +2558,9 @@ } }, "node_modules/@csstools/postcss-media-minmax": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.1.4.tgz", - "integrity": "sha512-xl/PIO3TUbXO1ZA4SA6HCw+Q9UGe2cgeRKx3lHCzoNig2D4bT5vfVCOrwhxjUb09oHihc9eI3I0iIfVPiXaN1A==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.1.8.tgz", + "integrity": "sha512-KYQCal2i7XPNtHAUxCECdrC7tuxIWQCW+s8eMYs5r5PaAiVTeKwlrkRS096PFgojdNCmHeG0Cb7njtuNswNf+w==", "funding": [ { "type": "github", @@ -2717,11 +2571,12 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { - "@csstools/css-calc": "^1.2.0", - "@csstools/css-parser-algorithms": "^2.6.1", - "@csstools/css-tokenizer": "^2.2.4", - "@csstools/media-query-list-parser": "^2.1.9" + "@csstools/css-calc": "^1.2.4", + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1", + "@csstools/media-query-list-parser": "^2.1.13" }, "engines": { "node": "^14 || ^16 || >=18" @@ -2744,6 +2599,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-parser-algorithms": "^2.2.0", "@csstools/css-tokenizer": "^2.1.1", @@ -2760,6 +2616,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-2.0.2.tgz", "integrity": "sha512-jbwrP8rN4e7LNaRcpx3xpMUjhtt34I9OV+zgbcsYAAk6k1+3kODXJBf95/JMYWhu9g1oif7r06QVUgfWsKxCFw==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2778,6 +2635,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-2.0.1.tgz", "integrity": "sha512-TQT5g3JQ5gPXC239YuRK8jFceXF9d25ZvBkyjzBGGoW5st5sPXFVQS8OjYb9IJ/K3CdfK4528y483cgS2DJR/w==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2806,6 +2664,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2833,6 +2692,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2857,6 +2717,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2874,6 +2735,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-2.0.2.tgz", "integrity": "sha512-6Pvo4uexUCXt+Hz5iUtemQAcIuCYnL+ePs1khFR6/xPgC92aQLJ0zGHonWoewiBE+I++4gXK3pr+R1rlOFHe5w==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -2892,6 +2754,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-2.1.1.tgz", "integrity": "sha512-YCvdF0GCZK35nhLgs7ippcxDlRVe5QsSht3+EghqTjnYnyl3BbWIN6fYQ1dKWYTJ+7Bgi41TgqQFfJDcp9Xy/w==", + "license": "CC0-1.0", "dependencies": { "@csstools/css-calc": "^1.1.1", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2922,6 +2785,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/color-helpers": "^2.1.0", "postcss-value-parser": "^4.2.0" @@ -2947,6 +2811,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "engines": { "node": "^14 || ^16 || >=18" } @@ -2955,6 +2820,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-2.1.1.tgz", "integrity": "sha512-XcXmHEFfHXhvYz40FtDlA4Fp4NQln2bWTsCwthd2c+MCnYArUYU3YaMqzR5CrKP3pMoGYTBnp5fMqf1HxItNyw==", + "license": "CC0-1.0", "dependencies": { "@csstools/css-calc": "^1.1.1", "@csstools/css-parser-algorithms": "^2.1.1", @@ -2975,6 +2841,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-2.0.1.tgz", "integrity": "sha512-oJ9Xl29/yU8U7/pnMJRqAZd4YXNCfGEdcP4ywREuqm/xMqcgDNDppYRoCGDt40aaZQIEKBS79LytUDN/DHf0Ew==", + "license": "CC0-1.0", "engines": { "node": "^14 || ^16 || >=18" }, @@ -2990,6 +2857,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "license": "CC0-1.0", "engines": { "node": "^14 || ^16 || >=18" }, @@ -3015,6 +2883,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT-0", "engines": { "node": "^14 || ^16 || >=18" }, @@ -3022,54 +2891,6 @@ "postcss": "^8.4" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", @@ -3078,6 +2899,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3086,314 +2908,31 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -3403,6 +2942,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -3426,6 +2966,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -3441,6 +2982,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3449,10 +2991,11 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -3461,6 +3004,7 @@ "version": "1.7.19", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", + "license": "MIT", "dependencies": { "@tanstack/react-virtual": "^3.0.0-beta.60", "client-only": "^0.0.1" @@ -3474,12 +3018,14 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -3492,6 +3038,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -3504,17 +3051,19 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@inquirer/core": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.0.1.tgz", - "integrity": "sha512-KKTgjViBQUi3AAssqjUFMnMO3CM3qwCHvePV9EW+zTKGKafFGFF01sc1yOIYjLJ7QU52G/FbzKc+c01WLzXmVQ==", + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.4.tgz", + "integrity": "sha512-5y4/PUJVnRb4bwWY67KLdebWOhOc7xj5IP2J80oWXa64mVag24rwQ1VAdnj7/eDY/odhguW0zQ1Mp1pj6fO/2w==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/figures": "^1.0.7", - "@inquirer/type": "^3.0.0", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", "ansi-escapes": "^4.3.2", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", @@ -3528,9 +3077,9 @@ } }, "node_modules/@inquirer/core/node_modules/@inquirer/type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.0.tgz", - "integrity": "sha512-YYykfbw/lefC7yKj7nanzQXILM7r3suIvyFlCcMskc99axmsSewXWkAfXKwMbgxL76iAFVmRwmYdwNZNc8gjog==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", + "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", "dev": true, "license": "MIT", "engines": { @@ -3541,16 +3090,23 @@ } }, "node_modules/@inquirer/core/node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "version": "22.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz", + "integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, + "node_modules/@inquirer/core/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/@inquirer/core/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -3564,10 +3120,40 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@inquirer/core/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@inquirer/figures": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.7.tgz", - "integrity": "sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz", + "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==", "dev": true, "license": "MIT", "engines": { @@ -3579,6 +3165,7 @@ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -3592,10 +3179,11 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -3603,40 +3191,12 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -3647,27 +3207,11 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@jest/expect-utils": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" }, @@ -3679,6 +3223,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -3690,6 +3235,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -3703,10 +3249,11 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3721,6 +3268,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -3730,31 +3278,35 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@jsdoc/salty": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", - "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.9.tgz", + "integrity": "sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21" }, @@ -3763,9 +3315,9 @@ } }, "node_modules/@mswjs/interceptors": { - "version": "0.36.9", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.36.9.tgz", - "integrity": "sha512-mMRDUBwSNeCgjSMEWfjoh4Rm9fbyZ7xQ9SBq8eGHiiyRn1ieTip3pNEt0wxWVPPxR4i1Rv9bTkeEbkX7M4c15A==", + "version": "0.37.5", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.5.tgz", + "integrity": "sha512-AAwRb5vXFcY4L+FvZ7LZusDuZ0vEe0Zm8ohn1FM6/X7A3bj4mqmkAcGRWuvC2JwSygNwHAAmMnAI73vPHeqsHA==", "dev": true, "license": "MIT", "dependencies": { @@ -3785,6 +3337,7 @@ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dev": true, + "license": "MIT", "dependencies": { "eslint-scope": "5.1.1" } @@ -3794,6 +3347,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -3807,6 +3361,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3816,6 +3371,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -3829,6 +3385,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -3838,6 +3395,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -3871,11 +3429,68 @@ "dev": true, "license": "MIT" }, + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=14" @@ -3886,6 +3501,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/base64": { @@ -3893,6 +3509,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/codegen": { @@ -3900,6 +3517,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/eventemitter": { @@ -3907,6 +3525,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/fetch": { @@ -3914,6 +3533,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dev": true, + "license": "BSD-3-Clause", "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", @@ -3925,6 +3545,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/inquire": { @@ -3932,6 +3553,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/path": { @@ -3939,6 +3561,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/pool": { @@ -3946,6 +3569,7 @@ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@protobufjs/utf8": { @@ -3953,26 +3577,29 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true, + "license": "BSD-3-Clause", "peer": true }, "node_modules/@rollup/plugin-commonjs": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz", - "integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.2.tgz", + "integrity": "sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", - "glob": "^8.0.3", + "fdir": "^6.2.0", "is-reference": "1.2.1", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0 || 14 >= 14.17" }, "peerDependencies": { - "rollup": "^3.29.5" + "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -3981,20 +3608,21 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^3.29.5" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -4002,22 +3630,32 @@ } } }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@rushstack/eslint-patch": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.2.tgz", - "integrity": "sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==", - "dev": true + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.5.tgz", + "integrity": "sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==", + "dev": true, + "license": "MIT" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "license": "MIT" }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4034,6 +3672,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" }, @@ -4050,6 +3689,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" }, @@ -4066,6 +3706,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4082,6 +3723,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4098,6 +3740,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4114,6 +3757,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4130,6 +3774,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4146,6 +3791,7 @@ "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", "dev": true, + "license": "MIT", "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", "@svgr/babel-plugin-remove-jsx-attribute": "*", @@ -4172,6 +3818,7 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.19.6", "@svgr/babel-preset": "^6.5.1", @@ -4192,6 +3839,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4204,6 +3852,7 @@ "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.20.0", "entities": "^4.4.0" @@ -4221,6 +3870,7 @@ "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.19.6", "@svgr/babel-preset": "^6.5.1", @@ -4239,35 +3889,38 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz", - "integrity": "sha512-rtvo7KwuIvqK9zb0VZ5IL7fiJAEnG+0EiFZz8FUOs+2mhGqdGmjKIaT1XU7Zq0eFqL0jonLlhbayJI/J2SA/Bw==", + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.11.2.tgz", + "integrity": "sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ==", + "license": "MIT", "dependencies": { - "@tanstack/virtual-core": "3.5.0" + "@tanstack/virtual-core": "3.11.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@tanstack/virtual-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.0.tgz", - "integrity": "sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==", + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz", + "integrity": "sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@testing-library/dom": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", - "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", @@ -4288,6 +3941,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", "dev": true, + "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.0.1", "@babel/runtime": "^7.9.2", @@ -4310,6 +3964,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4323,6 +3978,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.7.tgz", "integrity": "sha512-tzRNp7pzd5QmbtXNG/mhdcl7Awfu/Iz1RaVHY75zTdOkmHCuzMhRL83gWHSgOAcjS3CCbyfwUHMZgRJb4kAfpA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^7.28.1" @@ -4340,6 +3996,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-5.1.3.tgz", "integrity": "sha512-UdEUtlQapQ579NEcXDAUE275u+KUsPtxW7NmFrNt0bE6lW8lqNCyxDK0RSuECmNZ/S0/fgP00W9RWRhVKO/hRg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "@types/react": ">=16.9.0", @@ -4367,6 +4024,7 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -4383,6 +4041,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -4401,13 +4060,15 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@testing-library/react/node_modules/@types/yargs": { "version": "15.0.19", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -4417,6 +4078,7 @@ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.10.2", "@babel/runtime-corejs3": "^7.10.2" @@ -4430,6 +4092,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -4441,10 +4104,11 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.5.2", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", - "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12", "npm": ">=6" @@ -4458,6 +4122,7 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -4466,6 +4131,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "license": "ISC", "engines": { "node": ">=10.13.0" } @@ -4475,19 +4141,22 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", - "dev": true + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", + "dev": true, + "license": "MIT" }, "node_modules/@types/chai-subset": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz", "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==", "dev": true, + "license": "MIT", "dependencies": { "@types/chai": "*" } @@ -4540,12 +4209,14 @@ "node_modules/@types/d3-array": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT" }, "node_modules/@types/d3-axis": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", "dependencies": { "@types/d3-selection": "*" } @@ -4554,6 +4225,7 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", "dependencies": { "@types/d3-selection": "*" } @@ -4561,17 +4233,20 @@ "node_modules/@types/d3-chord": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" }, "node_modules/@types/d3-color": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" }, "node_modules/@types/d3-contour": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" @@ -4580,17 +4255,20 @@ "node_modules/@types/d3-delaunay": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" }, "node_modules/@types/d3-dispatch": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", + "license": "MIT" }, "node_modules/@types/d3-drag": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", "dependencies": { "@types/d3-selection": "*" } @@ -4598,35 +4276,41 @@ "node_modules/@types/d3-dsv": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" }, "node_modules/@types/d3-ease": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" }, "node_modules/@types/d3-fetch": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", "dependencies": { "@types/d3-dsv": "*" } }, "node_modules/@types/d3-force": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.9.tgz", - "integrity": "sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA==" + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" }, "node_modules/@types/d3-format": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" }, "node_modules/@types/d3-geo": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", "dependencies": { "@types/geojson": "*" } @@ -4634,12 +4318,14 @@ "node_modules/@types/d3-hierarchy": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" }, "node_modules/@types/d3-interpolate": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", "dependencies": { "@types/d3-color": "*" } @@ -4647,68 +4333,80 @@ "node_modules/@types/d3-path": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "license": "MIT" }, "node_modules/@types/d3-polygon": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" }, "node_modules/@types/d3-quadtree": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" }, "node_modules/@types/d3-random": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" }, "node_modules/@types/d3-scale": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "license": "MIT", "dependencies": { "@types/d3-time": "*" } }, "node_modules/@types/d3-scale-chromatic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" }, "node_modules/@types/d3-selection": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", - "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==" + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" }, "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", "dependencies": { "@types/d3-path": "*" } }, "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" }, "node_modules/@types/d3-time-format": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" }, "node_modules/@types/d3-timer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" }, "node_modules/@types/d3-transition": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz", - "integrity": "sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", "dependencies": { "@types/d3-selection": "*" } @@ -4717,46 +4415,53 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" } }, "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/geojson": { - "version": "7946.0.14", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + "version": "7946.0.15", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz", + "integrity": "sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==", + "license": "MIT" }, "node_modules/@types/history": { "version": "4.7.11", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "license": "MIT" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -4765,14 +4470,16 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -4782,6 +4489,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -4793,6 +4501,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -4805,107 +4514,122 @@ "node_modules/@types/jest/node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", - "dev": true + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.14.tgz", + "integrity": "sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A==", + "license": "MIT" }, "node_modules/@types/lodash-es": { "version": "4.17.12", "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/lodash": "*" } }, "node_modules/@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, + "license": "MIT", "dependencies": { - "@types/linkify-it": "*", - "@types/mdurl": "*" + "@types/linkify-it": "^5", + "@types/mdurl": "^2" } }, "node_modules/@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT" }, "node_modules/@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "16.18.96", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.96.tgz", - "integrity": "sha512-84iSqGXoO+Ha16j8pRZ/L90vDMKX04QTYMTfYeE1WrjWaZXuchBehGUZEpNgx7JnmlrIHdnABmpjrQjhCnNldQ==" + "version": "16.18.124", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.124.tgz", + "integrity": "sha512-8ADCm5WzM/IpWxjs1Jhtwo6j+Fb8z4yr/CobP5beUUPdyCI0mg87/bqQYxNcqnhZ24Dc9RME8SQWu5eI/FmSGA==", + "license": "MIT" }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "dev": true, - "dependencies": { - "@types/react": "*" + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/react-router": { "version": "5.1.20", "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "license": "MIT", "dependencies": { "@types/history": "^4.7.11", "@types/react": "*" @@ -4915,6 +4639,7 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "license": "MIT", "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -4922,10 +4647,11 @@ } }, "node_modules/@types/react-test-renderer": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.3.0.tgz", - "integrity": "sha512-HW4MuEYxfDbOHQsVlY/XtOvNHftCVEPhJF2pQXXwcUiUF+Oyb0usgp48HSgpK5rt8m9KZb22yqOeZm+rrVG8gw==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-19.0.0.tgz", + "integrity": "sha512-qDVnNybqFm2eZKJ4jD34EvRd6VHD67KjgnWaEMM0Id9L22EpWe3nOSVKHWL1XWRCxUWe3lhXwlEeCKD1BlJCQA==", "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } @@ -4933,18 +4659,21 @@ "node_modules/@types/resize-observer-browser": { "version": "0.1.11", "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", - "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==" + "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==", + "license": "MIT" }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" }, "node_modules/@types/statuses": { "version": "2.0.5", @@ -4958,6 +4687,7 @@ "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", "dev": true, + "license": "MIT", "dependencies": { "@types/jest": "*" } @@ -4970,9 +4700,10 @@ "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -4980,13 +4711,15 @@ "node_modules/@types/yargs-parser": { "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -5016,26 +4749,12 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5043,17 +4762,12 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/experimental-utils": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/utils": "5.62.0" }, @@ -5073,6 +4787,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -5100,6 +4815,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0" @@ -5117,6 +4833,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", @@ -5144,6 +4861,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5157,6 +4875,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0", @@ -5179,26 +4898,12 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5206,17 +4911,12 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/utils": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -5243,6 +4943,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -5256,30 +4957,17 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5287,17 +4975,12 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/utils/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" @@ -5311,16 +4994,18 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "dev": true, + "license": "ISC" }, "node_modules/@vitejs/plugin-react": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz", "integrity": "sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.20.12", "@babel/plugin-transform-react-jsx-self": "^7.18.6", @@ -5332,7 +5017,20 @@ "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.5.4" + "vite": "^4.1.0-beta.0" + } + }, + "node_modules/@vitejs/plugin-react/node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" } }, "node_modules/@vitest/expect": { @@ -5340,6 +5038,7 @@ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.29.8.tgz", "integrity": "sha512-xlcVXn5I5oTq6NiZSY3ykyWixBxr5mG8HYtjvpgg6KaqHm0mvhX18xuwl5YGxIRNt/A5jidd7CWcNHrSvgaQqQ==", "dev": true, + "license": "MIT", "dependencies": { "@vitest/spy": "0.29.8", "@vitest/utils": "0.29.8", @@ -5351,6 +5050,7 @@ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.29.8.tgz", "integrity": "sha512-FzdhnRDwEr/A3Oo1jtIk/B952BBvP32n1ObMEb23oEJNO+qO5cBet6M2XWIDQmA7BDKGKvmhUf2naXyp/2JEwQ==", "dev": true, + "license": "MIT", "dependencies": { "@vitest/utils": "0.29.8", "p-limit": "^4.0.0", @@ -5362,6 +5062,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^1.0.0" }, @@ -5373,10 +5074,11 @@ } }, "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.20" }, @@ -5389,6 +5091,7 @@ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.29.8.tgz", "integrity": "sha512-VdjBe9w34vOMl5I5mYEzNX8inTxrZ+tYUVk9jxaZJmHFwmDFC/GV3KBFTA/JKswr3XHvZL+FE/yq5EVhb6pSAw==", "dev": true, + "license": "MIT", "dependencies": { "tinyspy": "^1.0.2" } @@ -5398,6 +5101,7 @@ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.29.8.tgz", "integrity": "sha512-qGzuf3vrTbnoY+RjjVVIBYfuWMjn3UMUqyQtdGNZ6ZIIyte7B37exj6LaVkrZiUTvzSadVvO/tJm8AEgbGCBPg==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^3.1.0", "diff": "^5.1.0", @@ -5409,20 +5113,23 @@ "version": "2.36.0", "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz", "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -5432,10 +5139,11 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5448,6 +5156,7 @@ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.1.0", "acorn-walk": "^8.0.2" @@ -5458,15 +5167,20 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -5476,6 +5190,7 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "4" }, @@ -5488,6 +5203,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5504,10 +5220,33 @@ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.1.0" } }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -5542,6 +5281,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5550,6 +5290,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5564,12 +5305,15 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -5578,6 +5322,19 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/arch": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", @@ -5596,37 +5353,42 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -5640,6 +5402,7 @@ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -5660,6 +5423,7 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5669,6 +5433,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -5689,6 +5454,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -5705,15 +5471,16 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5723,15 +5490,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5740,45 +5508,37 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, "node_modules/array.prototype.tosorted": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", - "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.1.0", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -5792,6 +5552,7 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5801,6 +5562,7 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -5809,13 +5571,15 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5824,12 +5588,13 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -5844,12 +5609,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -5867,6 +5633,7 @@ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -5878,21 +5645,23 @@ } }, "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", "dev": true, + "license": "MPL-2.0", "engines": { "node": ">=4" } }, "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, - "dependencies": { - "dequal": "^2.0.3" + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/babel-plugin-macros": { @@ -5900,6 +5669,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -5911,13 +5681,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -5925,25 +5696,27 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5953,13 +5726,15 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-preset-react-app": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", "@babel/plugin-proposal-class-properties": "^7.16.0", @@ -5982,12 +5757,14 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", "engines": { "node": ">=0.6" } @@ -5996,6 +5773,8 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -6007,18 +5786,21 @@ "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" }, "node_modules/boxen": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz", "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^7.0.0", @@ -6036,35 +5818,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/boxen/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/boxen/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -6072,43 +5831,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/boxen/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/boxen/node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -6116,27 +5844,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/boxen/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6158,6 +5870,7 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz", "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.7.2", "detect-node": "^2.1.0", @@ -6170,9 +5883,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "funding": [ { "type": "opencollective", @@ -6187,11 +5900,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -6204,6 +5918,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6213,6 +5928,7 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6222,21 +5938,53 @@ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -6250,6 +5998,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6259,6 +6008,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -6271,6 +6021,7 @@ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -6280,6 +6031,7 @@ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", @@ -6297,14 +6049,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001614", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", - "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==", + "version": "1.0.30001695", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz", + "integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==", "funding": [ { "type": "opencollective", @@ -6318,13 +6071,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.15" }, @@ -6333,10 +6088,11 @@ } }, "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, + "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -6344,7 +6100,7 @@ "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" }, "engines": { "node": ">=4" @@ -6354,6 +6110,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6370,6 +6127,7 @@ "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.2" }, @@ -6385,6 +6143,7 @@ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" }, @@ -6393,37 +6152,18 @@ } }, "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" } }, "node_modules/ci-info": { @@ -6436,6 +6176,7 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } @@ -6443,18 +6184,21 @@ "node_modules/classcat": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", - "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==" + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", + "license": "MIT" }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" }, "node_modules/cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6467,6 +6211,7 @@ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", "dev": true, + "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^5.0.0" @@ -6478,23 +6223,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/cli-truncate/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6507,6 +6241,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6519,6 +6254,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -6530,38 +6266,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -6575,13 +6279,15 @@ "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" }, "node_modules/clipboardy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", "dev": true, + "license": "MIT", "dependencies": { "arch": "^2.2.0", "execa": "^5.1.1", @@ -6599,6 +6305,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -6608,11 +6315,34 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6629,14 +6359,29 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -6647,19 +6392,32 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -6671,6 +6429,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", "engines": { "node": ">= 10" } @@ -6679,13 +6438,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -6698,6 +6459,7 @@ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -6716,6 +6478,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6724,35 +6487,41 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/compute-scroll-into-view": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-2.0.4.tgz", - "integrity": "sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g==" + "integrity": "sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g==", + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", - "dev": true + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6761,7 +6530,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.7.2", @@ -6774,12 +6544,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", - "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", + "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.24.3" }, "funding": { "type": "opencollective", @@ -6787,11 +6558,12 @@ } }, "node_modules/core-js-pure": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.0.tgz", - "integrity": "sha512-d3BrpyFr5eD4KcbRvQ3FTUx/KWmaDesr7+a3+1+P46IUnNoEt+oiLijPINZMEon7w9oGkIINWxrBAU9DEciwFQ==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.40.0.tgz", + "integrity": "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==", "dev": true, "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -6802,6 +6574,7 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -6814,19 +6587,21 @@ } }, "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", "dev": true, + "license": "MIT", "dependencies": { - "node-fetch": "^2.6.12" + "node-fetch": "^2.7.0" } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6840,6 +6615,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-5.0.2.tgz", "integrity": "sha512-aCU4AZ7uEcVSUzagTlA9pHciz7aWPKA/YzrEkpdSopJ2pvhIxiQ5sYeMz1/KByxlIo4XBdvMNJAVKMg/GRnhfw==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -6855,10 +6631,11 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", - "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12 || >=16" } @@ -6867,6 +6644,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-5.0.2.tgz", "integrity": "sha512-q+U+4QdwwB7T9VEW/LyO6CFrLAeLqOykC5mDqJXc7aKZAhDbq7BvGT13VGJe+IwBfdN2o3Xdw2kJ5IxwV1Sc9Q==", + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.1", "postcss-selector-parser": "^6.0.10", @@ -6887,6 +6665,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-8.0.2.tgz", "integrity": "sha512-OvFghizHJ45x7nsJJUSYLyQNTzsCU8yWjxAc/nhPQg1pbs18LMoET8N3kOweFDPy0JV0OSXN2iqRFhPBHYOeMA==", + "license": "CC0-1.0", "engines": { "node": "^14 || ^16 || >=18" }, @@ -6902,6 +6681,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -6917,6 +6697,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -6929,6 +6710,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -6940,7 +6722,8 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cssdb": { "version": "7.11.2", @@ -6955,12 +6738,14 @@ "type": "github", "url": "https://github.com/sponsors/csstools" } - ] + ], + "license": "CC0-1.0" }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -6972,6 +6757,7 @@ "version": "5.0.5", "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", "dependencies": { "css-tree": "~2.2.0" }, @@ -6984,6 +6770,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" @@ -6996,13 +6783,15 @@ "node_modules/csso/node_modules/mdn-data": { "version": "2.0.28", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" }, "node_modules/cssstyle": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dev": true, + "license": "MIT", "dependencies": { "rrweb-cssom": "^0.6.0" }, @@ -7013,12 +6802,14 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" }, "node_modules/d3": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -7059,6 +6850,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", "dependencies": { "internmap": "1 - 2" }, @@ -7070,6 +6862,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7078,6 +6871,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -7093,6 +6887,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", "dependencies": { "d3-path": "1 - 3" }, @@ -7104,6 +6899,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7112,6 +6908,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", "dependencies": { "d3-array": "^3.2.0" }, @@ -7123,6 +6920,7 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", "dependencies": { "delaunator": "5" }, @@ -7134,6 +6932,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7142,6 +6941,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -7154,6 +6954,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", "dependencies": { "commander": "7", "iconv-lite": "0.6", @@ -7174,21 +6975,11 @@ "node": ">=12" } }, - "node_modules/d3-dsv/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", "engines": { "node": ">=12" } @@ -7197,6 +6988,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", "dependencies": { "d3-dsv": "1 - 3" }, @@ -7208,6 +7000,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", @@ -7221,6 +7014,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7229,6 +7023,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -7240,6 +7035,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7248,6 +7044,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3" }, @@ -7259,6 +7056,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7267,6 +7065,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7275,6 +7074,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7283,6 +7083,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7291,6 +7092,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -7306,6 +7108,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -7318,6 +7121,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7326,6 +7130,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", "dependencies": { "d3-path": "^3.1.0" }, @@ -7337,6 +7142,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", "dependencies": { "d3-array": "2 - 3" }, @@ -7348,6 +7154,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", "dependencies": { "d3-time": "1 - 3" }, @@ -7359,6 +7166,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -7367,6 +7175,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -7385,6 +7194,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -7400,13 +7210,15 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/data-urls": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", "dev": true, + "license": "MIT", "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", @@ -7417,14 +7229,15 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7434,29 +7247,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -7468,17 +7283,19 @@ } }, "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7494,6 +7311,7 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7503,6 +7321,7 @@ "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, + "license": "MIT", "dependencies": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" @@ -7519,6 +7338,7 @@ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7527,21 +7347,24 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, + "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -7554,6 +7377,7 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -7562,13 +7386,15 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -7586,6 +7412,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -7602,6 +7429,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", "dependencies": { "robust-predicates": "^3.0.2" } @@ -7611,6 +7439,7 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -7620,26 +7449,43 @@ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -7648,6 +7494,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -7657,6 +7504,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -7668,13 +7516,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -7686,12 +7536,14 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -7710,7 +7562,8 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domexception": { "version": "4.0.0", @@ -7718,6 +7571,7 @@ "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", "deprecated": "Use your platform's native DOMException instead", "dev": true, + "license": "MIT", "dependencies": { "webidl-conversions": "^7.0.0" }, @@ -7729,6 +7583,7 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -7740,9 +7595,10 @@ } }, "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -7756,6 +7612,7 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/downshift/-/downshift-7.6.2.tgz", "integrity": "sha512-iOv+E1Hyt3JDdL9yYcOgW7nZ7GQ2Uz6YbggwXvKUSleetYhU2nXD482Rz6CzvM4lvI1At34BYruKAL4swRGxaA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.14.8", "compute-scroll-into-view": "^2.0.4", @@ -7767,27 +7624,46 @@ "react": ">=16.12.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.752", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.752.tgz", - "integrity": "sha512-P3QJreYI/AUTcfBVrC4zy9KvnZWekViThgQMX/VpJ+IsOBbcX5JFpORM4qWapwWQ+agb2nYAOyn/4PMXOk0m2Q==" + "version": "1.5.84", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.84.tgz", + "integrity": "sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==", + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -7796,6 +7672,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -7808,6 +7685,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -7816,62 +7694,69 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", "dependencies": { "stackframe": "^1.3.4" } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, + "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -7881,13 +7766,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7897,40 +7780,45 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.2" + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -7939,14 +7827,16 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -7957,19 +7847,21 @@ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -7984,6 +7876,7 @@ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -8016,9 +7909,10 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -8028,6 +7922,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8040,6 +7935,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -8057,16 +7953,18 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -8116,6 +8014,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", "@babel/eslint-parser": "^7.16.3", @@ -8144,6 +8043,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -8155,15 +8055,17 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -8181,6 +8083,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -8190,6 +8093,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "lodash": "^4.17.21", "string-natural-compare": "^3.0.1" @@ -8204,34 +8108,37 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, + "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/debug": { @@ -8239,6 +8146,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -8248,6 +8156,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -8260,6 +8169,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/experimental-utils": "^5.0.0" }, @@ -8280,65 +8190,76 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/eslint-plugin-react": { - "version": "7.34.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", - "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "version": "7.37.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", + "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", "dev": true, + "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlast": "^1.2.4", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.3", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.17", + "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7", - "object.hasown": "^1.1.3", - "object.values": "^1.1.7", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.10" + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { @@ -8346,6 +8267,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8358,6 +8280,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -8370,6 +8293,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -8387,6 +8311,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/utils": "^5.58.0" }, @@ -8403,6 +8328,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -8419,6 +8345,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -8431,6 +8358,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -8446,6 +8374,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -8458,6 +8387,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -8475,6 +8405,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -8484,10 +8415,11 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -8500,6 +8432,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -8512,6 +8445,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -8520,13 +8454,15 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -8536,6 +8472,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -8558,6 +8495,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", @@ -8573,19 +8511,21 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -8596,6 +8536,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -8607,46 +8548,74 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "dev": true, - "dependencies": { - "punycode": "^1.3.2" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.9.1" } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -8671,6 +8640,7 @@ "resolved": "https://registry.npmjs.org/filter-console/-/filter-console-0.1.1.tgz", "integrity": "sha512-zrXoV1Uaz52DqPs+qEwNJWJFAWZpYJ47UNmpN9q4j+/EYsz85uV0DC9k8tRND5kYmoVzL0W+Y75q4Rg8sRJCdg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8679,6 +8649,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8688,6 +8659,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -8704,6 +8676,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -8714,25 +8687,28 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -8749,6 +8725,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -8757,10 +8734,11 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dev": true, + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8774,6 +8752,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", "engines": { "node": "*" }, @@ -8785,13 +8764,16 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -8805,20 +8787,24 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -8832,6 +8818,7 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8841,6 +8828,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -8850,6 +8838,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -8859,21 +8848,28 @@ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -8882,11 +8878,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8895,14 +8906,15 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -8915,7 +8927,9 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8935,6 +8949,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -8947,6 +8962,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -8956,6 +8972,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -8968,6 +8985,7 @@ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, + "license": "MIT", "dependencies": { "global-prefix": "^3.0.0" }, @@ -8980,6 +8998,7 @@ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, + "license": "MIT", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -8994,6 +9013,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -9006,6 +9026,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -9015,6 +9036,7 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -9031,6 +9053,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -9050,15 +9073,17 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9067,18 +9092,20 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/graphql": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", - "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", + "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", "dev": true, "license": "MIT", "engines": { @@ -9090,15 +9117,20 @@ "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9107,6 +9139,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -9116,6 +9149,7 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -9124,10 +9158,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -9136,10 +9174,11 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9152,6 +9191,7 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -9167,6 +9207,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -9181,25 +9222,11 @@ "dev": true, "license": "MIT" }, - "node_modules/highcharts": { - "version": "10.3.3", - "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-10.3.3.tgz", - "integrity": "sha512-r7wgUPQI9tr3jFDn3XT36qsNwEIZYcfgz4mkKEA6E4nn5p86y+u1EZjazIG4TRkl5/gmGRtkBUiZW81g029RIw==", - "peer": true - }, - "node_modules/highcharts-react-official": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/highcharts-react-official/-/highcharts-react-official-3.2.1.tgz", - "integrity": "sha512-hyQTX7ezCxl7JqumaWiGsroGWalzh24GedQIgO3vJbkGOZ6ySRAltIYjfxhrq4HszJOySZegotEF7v+haQ75UA==", - "peerDependencies": { - "highcharts": ">=6.0.0", - "react": ">=16.8.0" - } - }, "node_modules/history": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.7.6" } @@ -9208,6 +9235,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" } @@ -9215,13 +9243,15 @@ "node_modules/hoist-non-react-statics/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -9234,6 +9264,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -9245,13 +9276,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-encoding": "^2.0.0" }, @@ -9264,6 +9297,7 @@ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -9276,6 +9310,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -9290,6 +9325,7 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -9303,6 +9339,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -9316,25 +9353,40 @@ "node": ">=0.4" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immutable": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", - "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==" + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "license": "MIT" }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -9351,6 +9403,7 @@ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9360,6 +9413,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -9369,6 +9423,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9377,6 +9432,8 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -9385,23 +9442,26 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9411,18 +9471,21 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -9435,15 +9498,20 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", + "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9453,12 +9521,16 @@ } }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9468,6 +9540,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -9476,13 +9550,14 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9496,6 +9571,7 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9504,23 +9580,30 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, + "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -9531,12 +9614,14 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9550,6 +9635,7 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -9564,17 +9650,23 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9585,17 +9677,22 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9608,30 +9705,21 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "license": "MIT", "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "engines": { - "node": ">= 0.4" + "is-extglob": "^2.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { + "node_modules/is-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9656,12 +9744,14 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9675,6 +9765,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9684,6 +9775,7 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9693,6 +9785,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9702,6 +9795,7 @@ "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz", "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -9713,25 +9807,30 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -9745,6 +9844,7 @@ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9753,12 +9853,13 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -9772,6 +9873,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -9780,12 +9882,14 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9795,12 +9899,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9810,12 +9917,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -9829,6 +9937,7 @@ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9837,25 +9946,30 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -9869,6 +9983,7 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -9880,43 +9995,49 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/iserror": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/iserror/-/iserror-0.0.2.tgz", - "integrity": "sha512-oKGGrFVaWwETimP3SiWwjDeY27ovZoyZPHtxblC4hCq9fXxed/jasx+ATWFFjCVSRZng8VTMsN1nDnGo6zMBSw==" + "integrity": "sha512-oKGGrFVaWwETimP3SiWwjDeY27ovZoyZPHtxblC4hCq9fXxed/jasx+ATWFFjCVSRZng8VTMsN1nDnGo6zMBSw==", + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "dev": true, + "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -9928,6 +10049,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -9942,6 +10064,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -9953,6 +10076,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -9965,12 +10089,14 @@ "node_modules/jest-diff/node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -9979,6 +10105,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", @@ -9993,6 +10120,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -10004,6 +10132,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -10016,12 +10145,14 @@ "node_modules/jest-matcher-utils/node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/jest-message-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -10041,6 +10172,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -10052,6 +10184,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -10064,12 +10197,14 @@ "node_modules/jest-message-util/node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -10082,11 +10217,24 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, + "license": "MIT", "bin": { "jiti": "bin/jiti.js" } @@ -10094,18 +10242,21 @@ "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -10118,26 +10269,28 @@ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "xmlcreate": "^2.0.4" } }, "node_modules/jsdoc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", - "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz", + "integrity": "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@babel/parser": "^7.20.15", "@jsdoc/salty": "^0.2.1", - "@types/markdown-it": "^12.2.3", + "@types/markdown-it": "^14.1.1", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", @@ -10156,6 +10309,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -10165,6 +10319,7 @@ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.2.tgz", "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", "dev": true, + "license": "MIT", "dependencies": { "abab": "^2.0.6", "acorn": "^8.8.2", @@ -10190,7 +10345,7 @@ "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^12.0.1", - "ws": "^8.17.1", + "ws": "^8.13.0", "xml-name-validator": "^4.0.0" }, "engines": { @@ -10206,46 +10361,52 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -10258,6 +10419,7 @@ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -10273,6 +10435,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -10282,6 +10445,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10291,6 +10455,7 @@ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.9" } @@ -10299,19 +10464,22 @@ "version": "0.26.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", - "dev": true + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" }, "node_modules/language-tags": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, + "license": "MIT", "dependencies": { "language-subtag-registry": "^0.3.20" }, @@ -10324,6 +10492,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -10333,27 +10502,33 @@ } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, + "license": "MIT", "dependencies": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "node_modules/local-pkg": { @@ -10361,6 +10536,7 @@ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" }, @@ -10373,6 +10549,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -10387,42 +10564,49 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==", "dev": true, + "license": "Apache-2.0", "peer": true }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -10435,6 +10619,7 @@ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } @@ -10444,6 +10629,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -10453,20 +10639,19 @@ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, + "license": "MIT", "bin": { "lz-string": "bin/bin.js" } }, "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/map-obj": { @@ -10474,6 +10659,7 @@ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -10482,19 +10668,21 @@ } }, "node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "bin": { - "markdown-it": "bin/markdown-it.js" + "markdown-it": "bin/markdown-it.mjs" } }, "node_modules/markdown-it-anchor": { @@ -10502,25 +10690,18 @@ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", "dev": true, + "license": "Unlicense", "peerDependencies": { "@types/markdown-it": "*", "markdown-it": "*" } }, - "node_modules/markdown-it/node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true, + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -10532,16 +10713,28 @@ "version": "6.3.4", "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz", "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.8", "remove-accents": "0.5.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -10550,19 +10743,22 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" }, "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" }, "node_modules/meow": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", @@ -10589,6 +10785,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -10600,13 +10797,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -10615,6 +10814,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -10623,16 +10823,30 @@ "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/microseconds": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", - "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" + "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==", + "license": "MIT" }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -10642,6 +10856,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -10654,6 +10869,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -10663,6 +10879,7 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -10671,6 +10888,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -10683,6 +10901,7 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10692,6 +10911,7 @@ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, + "license": "MIT", "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", @@ -10702,10 +10922,11 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -10715,6 +10936,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -10723,46 +10945,55 @@ } }, "node_modules/mlly": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", - "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", "dev": true, + "license": "MIT", "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.0.3", - "ufo": "^1.3.2" + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" } }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/msw": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.6.0.tgz", - "integrity": "sha512-n3tx2w0MZ3H4pxY0ozrQ4sNPzK/dGtlr2cIIyuEsgq2Bhy4wvcW6ZH2w/gXM9+MEUY6HC1fWhqtcXDxVZr5Jxw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.7.0.tgz", + "integrity": "sha512-BIodwZ19RWfCbYTxWTUfTXc+sg4OwjCAgxU1ZsgmggX/7S3LdUifsbUPJs61j0rWb19CZRGY5if77duhc0uXzw==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { - "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/cookie": "^2.0.1", "@bundled-es-modules/statuses": "^1.0.1", "@bundled-es-modules/tough-cookie": "^0.1.6", "@inquirer/confirm": "^5.0.0", - "@mswjs/interceptors": "^0.36.5", + "@mswjs/interceptors": "^0.37.0", "@open-draft/deferred-promise": "^2.2.0", "@open-draft/until": "^2.1.0", "@types/cookie": "^0.6.0", "@types/statuses": "^2.0.4", - "chalk": "^4.1.2", "graphql": "^16.8.1", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", "strict-event-emitter": "^0.5.1", "type-fest": "^4.26.1", "yargs": "^17.7.2" @@ -10786,14 +11017,14 @@ } }, "node_modules/msw/node_modules/@inquirer/confirm": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.1.tgz", - "integrity": "sha512-6ycMm7k7NUApiMGfVc32yIPp28iPKxhGRMqoNDiUjq2RyTAkbs5Fx0TdzBqhabcKvniDdAAvHCmsRjnNfTsogw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.3.tgz", + "integrity": "sha512-fuF9laMmHoOgWapF9h9hv6opA5WvmGFHsTYGCmuFxcghIhEhb3dN0CdQR4BUMqa2H506NCj8cGX4jwMsE4t6dA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.0.1", - "@inquirer/type": "^3.0.0" + "@inquirer/core": "^10.1.4", + "@inquirer/type": "^3.0.2" }, "engines": { "node": ">=18" @@ -10803,9 +11034,9 @@ } }, "node_modules/msw/node_modules/@inquirer/type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.0.tgz", - "integrity": "sha512-YYykfbw/lefC7yKj7nanzQXILM7r3suIvyFlCcMskc99axmsSewXWkAfXKwMbgxL76iAFVmRwmYdwNZNc8gjog==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", + "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", "dev": true, "license": "MIT", "engines": { @@ -10816,14 +11047,14 @@ } }, "node_modules/msw/node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "version": "22.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz", + "integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, "node_modules/msw/node_modules/path-to-regexp": { @@ -10848,6 +11079,7 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -10858,20 +11090,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", + "license": "ISC", "dependencies": { "big-integer": "^1.6.16" } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10883,28 +11117,39 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/natural-compare-lite": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -10924,34 +11169,39 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", @@ -10962,26 +11212,12 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -10989,16 +11225,12 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11007,14 +11239,15 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/npm": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.0.tgz", - "integrity": "sha512-wh93uRczgp7HDnPMiLXcCkv2hagdJS0zJ9KT/31d0FoXP02+qgN2AOwpaW85fxRWkinl2rELfPw+CjBXW48/jQ==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.2.tgz", + "integrity": "sha512-iriPEPIkoMYUy3F6f3wwSZAU93E0Eg6cHwIR6jzzOXWSy+SD/rOODEs74cVONHKSx2obXtuUoyidVEhISrisgQ==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -11086,75 +11319,83 @@ "write-file-atomic" ], "dev": true, + "license": "Artistic-2.0", + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.5.2", - "@npmcli/config": "^8.3.2", - "@npmcli/fs": "^3.1.1", - "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.1.0", - "@npmcli/promise-spawn": "^7.0.2", - "@npmcli/redact": "^2.0.0", - "@npmcli/run-script": "^8.1.0", - "@sigstore/tuf": "^2.3.3", - "abbrev": "^2.0.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.2", + "@npmcli/package-json": "^6.1.0", + "@npmcli/promise-spawn": "^8.0.2", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "@sigstore/tuf": "^3.0.0", + "abbrev": "^3.0.0", "archy": "~1.0.0", - "cacache": "^18.0.3", + "cacache": "^19.0.1", "chalk": "^5.3.0", - "ci-info": "^4.0.0", + "ci-info": "^4.1.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.3.15", + "glob": "^10.4.5", "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.2", - "ini": "^4.1.2", - "init-package-json": "^6.0.3", - "is-cidr": "^5.0.5", - "json-parse-even-better-errors": "^3.0.2", - "libnpmaccess": "^8.0.6", - "libnpmdiff": "^6.1.2", - "libnpmexec": "^8.1.1", - "libnpmfund": "^5.0.10", - "libnpmhook": "^10.0.5", - "libnpmorg": "^6.0.6", - "libnpmpack": "^7.0.2", - "libnpmpublish": "^9.0.8", - "libnpmsearch": "^7.0.5", - "libnpmteam": "^6.0.5", - "libnpmversion": "^6.0.2", - "make-fetch-happen": "^13.0.1", - "minimatch": "^9.0.4", + "hosted-git-info": "^8.0.2", + "ini": "^5.0.0", + "init-package-json": "^7.0.2", + "is-cidr": "^5.1.0", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.0", + "libnpmexec": "^9.0.0", + "libnpmfund": "^6.0.0", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.0", + "libnpmpublish": "^10.0.1", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.3", + "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.1.0", - "nopt": "^7.2.1", - "normalize-package-data": "^6.0.1", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.0.1", - "npm-profile": "^10.0.0", - "npm-registry-fetch": "^17.0.1", - "npm-user-validate": "^2.0.1", + "node-gyp": "^11.0.0", + "nopt": "^8.0.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.1", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.2", + "npm-user-validate": "^3.0.0", "p-map": "^4.0.0", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.1", - "proc-log": "^4.2.0", + "pacote": "^19.0.1", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", - "read": "^3.0.1", - "semver": "^7.6.2", + "read": "^4.0.0", + "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", - "ssri": "^10.0.6", + "ssri": "^12.0.0", "supports-color": "^9.4.0", "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.1", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" + "validate-npm-package-name": "^6.0.0", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "bin": { "npm": "bin/npm-cli.js", @@ -11169,6 +11410,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -11194,7 +11436,7 @@ } }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -11243,6 +11485,18 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", "dev": true, @@ -11250,7 +11504,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.2", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -11262,48 +11516,48 @@ "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.5.2", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.1", - "@npmcli/installed-package-contents": "^2.1.0", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.1.1", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.1.0", - "@npmcli/query": "^3.1.0", - "@npmcli/redact": "^2.0.0", - "@npmcli/run-script": "^8.1.0", - "bin-links": "^4.0.4", - "cacache": "^18.0.3", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.2", - "json-parse-even-better-errors": "^3.0.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", "json-stringify-nice": "^1.1.4", "lru-cache": "^10.2.2", "minimatch": "^9.0.4", - "nopt": "^7.2.1", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.0.1", - "npm-registry-fetch": "^17.0.1", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.0", - "proc-log": "^4.2.0", - "proggy": "^2.0.0", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", - "ssri": "^10.0.6", + "ssri": "^12.0.0", "treeverse": "^3.0.0", "walk-up-path": "^3.0.1" }, @@ -11311,30 +11565,30 @@ "arborist": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.3.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", "ci-info": "^4.0.0", - "ini": "^4.1.2", - "nopt": "^7.2.1", - "proc-log": "^4.2.0", - "read-package-json-fast": "^3.0.2", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -11342,159 +11596,191 @@ "semver": "^7.3.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.7", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^4.0.0", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "bin": { "installed-package-contents": "bin/index.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.6", + "version": "4.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" + "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.1.1", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^18.0.0", - "proc-log": "^4.1.0", + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^20.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "20.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.1.0", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", + "@npmcli/git": "^6.0.0", "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^4.0.0", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", "semver": "^7.5.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.2", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.1.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "8.1.0", + "version": "9.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "proc-log": "^4.0.0", - "which": "^4.0.0" + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@pkgjs/parseargs": { @@ -11507,27 +11793,6 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.3.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/core": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { "version": "0.3.2", "dev": true, @@ -11537,48 +11802,17 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.3.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.0", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.1", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.3.3", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.0", - "tuf-js": "^2.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/verify": { - "version": "1.2.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.1", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.1" + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@tufjs/canonical-json": { @@ -11590,26 +11824,13 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/agent-base": { @@ -11677,62 +11898,138 @@ "license": "MIT" }, "node_modules/npm/node_modules/bin-links": { - "version": "4.0.4", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "19.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "2.3.0", + "node_modules/npm/node_modules/cacache/node_modules/p-map": { + "version": "7.0.2", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", + "node_modules/npm/node_modules/cacache/node_modules/tar": { + "version": "7.4.3", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "balanced-match": "^1.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/npm/node_modules/cacache": { - "version": "18.0.3", + "node_modules/npm/node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=18" } }, "node_modules/npm/node_modules/chalk": { @@ -11757,7 +12054,7 @@ } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", + "version": "4.1.0", "dev": true, "funding": [ { @@ -11772,7 +12069,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.0.5", + "version": "4.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -11806,12 +12103,12 @@ } }, "node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.3", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/color-convert": { @@ -11839,7 +12136,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", @@ -11880,12 +12177,12 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.4", + "version": "4.3.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -11896,12 +12193,6 @@ } } }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/diff": { "version": "5.2.0", "dev": true, @@ -11964,7 +12255,7 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.1.1", + "version": "3.3.0", "dev": true, "inBundle": true, "license": "ISC", @@ -11991,33 +12282,22 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/function-bind": { - "version": "1.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/npm/node_modules/glob": { - "version": "10.3.15", + "version": "10.4.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.11.0" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -12028,20 +12308,8 @@ "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/hasown": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.2", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -12049,7 +12317,7 @@ "lru-cache": "^10.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/http-cache-semantics": { @@ -12072,7 +12340,7 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.4", + "version": "7.0.5", "dev": true, "inBundle": true, "license": "MIT", @@ -12098,7 +12366,7 @@ } }, "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.5", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -12106,7 +12374,7 @@ "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/imurmurhash": { @@ -12128,30 +12396,30 @@ } }, "node_modules/npm/node_modules/ini": { - "version": "4.1.2", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.3", + "version": "7.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/package-json": "^5.0.0", - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^3.0.1", + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/ip-address": { @@ -12180,29 +12448,17 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.0.5", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "^4.0.4" + "cidr-regex": "^4.1.1" }, "engines": { "node": ">=14" } }, - "node_modules/npm/node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/npm/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -12212,12 +12468,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/isexe": { "version": "2.0.0", "dev": true, @@ -12225,16 +12475,13 @@ "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { - "version": "2.3.6", + "version": "3.4.3", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -12249,12 +12496,12 @@ "license": "MIT" }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/json-stringify-nice": { @@ -12288,205 +12535,210 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.6", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1" + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.1.2", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.2", - "@npmcli/installed-package-contents": "^2.1.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", "tar": "^6.2.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "8.1.1", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.2", - "@npmcli/run-script": "^8.1.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", - "proc-log": "^4.2.0", - "read": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.10", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.2" + "@npmcli/arborist": "^8.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.5", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.6", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "7.0.2", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.2", - "@npmcli/run-script": "^8.1.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6" + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.8", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.1", - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.2.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", "semver": "^7.3.7", - "sigstore": "^2.2.0", - "ssri": "^10.0.6" + "sigstore": "^3.0.0", + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.5", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.5", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "6.0.2", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.7", - "@npmcli/run-script": "^8.1.0", - "json-parse-even-better-errors": "^3.0.2", - "proc-log": "^4.2.0", + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.7" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.2.2", + "version": "10.4.3", "dev": true, "inBundle": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.1", + "version": "14.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", + "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "ssri": "^10.0.0" + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.4", + "version": "9.0.5", "dev": true, "inBundle": true, "license": "ISC", @@ -12501,7 +12753,7 @@ } }, "node_modules/npm/node_modules/minipass": { - "version": "7.1.1", + "version": "7.1.2", "dev": true, "inBundle": true, "license": "ISC", @@ -12522,57 +12774,48 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.5", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "minizlib": "^3.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" }, "optionalDependencies": { "encoding": "^0.1.13" } }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", + "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { + "version": "3.0.1", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "minipass": "^3.0.0" + "minipass": "^7.0.4", + "rimraf": "^5.0.5" }, "engines": { - "node": ">= 8" + "node": ">= 18" } }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" + "node": ">= 8" } }, - "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { "version": "3.3.6", "dev": true, "inBundle": true, @@ -12676,25 +12919,16 @@ "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.1.0", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "MIT", @@ -12703,31 +12937,85 @@ "exponential-backoff": "^3.1.1", "glob": "^10.3.10", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^4.0.0" + "tar": "^7.4.3", + "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { + "node_modules/npm/node_modules/node-gyp/node_modules/chownr": { "version": "3.0.0", "dev": true, "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "dev": true, + "inBundle": true, "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, "node_modules/npm/node_modules/nopt": { - "version": "7.2.1", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -12737,48 +13025,56 @@ "bin": { "nopt": "bin/nopt.js" }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/nopt/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.1", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", + "hosted-git-info": "^8.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-normalize-package-bin": "^3.0.0" + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "6.3.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -12786,99 +13082,112 @@ "semver": "^7.1.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.2", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.4" + "ignore-walk": "^7.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.0.1", + "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-profile": { - "version": "10.0.0", + "version": "11.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.0.0" + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" }, "engines": { - "node": ">=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "17.0.1", + "version": "18.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/redact": "^2.0.0", - "make-fetch-happen": "^13.0.0", + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^4.0.0" + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" } }, "node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.1", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/p-map": { @@ -12896,49 +13205,55 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm/node_modules/package-json-from-dist": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0" + }, "node_modules/npm/node_modules/pacote": { - "version": "18.0.6", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/package-json": "^5.1.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^8.0.0", - "cacache": "^18.0.0", + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^17.0.0", - "proc-log": "^4.0.0", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "sigstore": "^2.2.0", - "ssri": "^10.0.0", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", "tar": "^6.1.11" }, "bin": { "pacote": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", + "json-parse-even-better-errors": "^4.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/path-key": { @@ -12967,7 +13282,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.16", + "version": "6.1.2", "dev": true, "inBundle": true, "license": "MIT", @@ -12980,21 +13295,21 @@ } }, "node_modules/npm/node_modules/proc-log": { - "version": "4.2.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/proggy": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/promise-all-reject-late": { @@ -13007,7 +13322,7 @@ } }, "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.1", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -13035,15 +13350,15 @@ } }, "node_modules/npm/node_modules/promzard": { - "version": "1.0.2", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "read": "^3.0.1" + "read": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/qrcode-terminal": { @@ -13055,37 +13370,37 @@ } }, "node_modules/npm/node_modules/read": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "mute-stream": "^1.0.0" + "mute-stream": "^2.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/read-cmd-shim": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/retry": { @@ -13097,6 +13412,21 @@ "node": ">= 4" } }, + "node_modules/npm/node_modules/rimraf": { + "version": "5.0.10", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", "dev": true, @@ -13105,7 +13435,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.6.2", + "version": "7.6.3", "dev": true, "inBundle": true, "license": "ISC", @@ -13150,20 +13480,72 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.3.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.1", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.1", - "@sigstore/sign": "^2.3.0", - "@sigstore/tuf": "^2.3.1", - "@sigstore/verify": "^1.2.0" + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/smart-buffer": { @@ -13191,14 +13573,14 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.3", + "version": "8.0.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", - "socks": "^2.7.1" + "socks": "^2.8.3" }, "engines": { "node": ">= 14" @@ -13241,7 +13623,7 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.17", + "version": "3.0.20", "dev": true, "inBundle": true, "license": "CC0-1.0" @@ -13253,7 +13635,7 @@ "license": "BSD-3-Clause" }, "node_modules/npm/node_modules/ssri": { - "version": "10.0.6", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -13261,7 +13643,7 @@ "minipass": "^7.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/string-width": { @@ -13402,33 +13784,46 @@ } }, "node_modules/npm/node_modules/tuf-js": { - "version": "2.2.1", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "unique-slug": "^4.0.0" + "unique-slug": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -13436,7 +13831,7 @@ "imurmurhash": "^0.1.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/util-deprecate": { @@ -13466,12 +13861,12 @@ } }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.1", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/walk-up-path": { @@ -13481,7 +13876,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/which": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -13492,7 +13887,7 @@ "node-which": "bin/which.js" }, "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/which/node_modules/isexe": { @@ -13555,7 +13950,7 @@ } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -13605,7 +14000,7 @@ } }, "node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -13614,7 +14009,7 @@ "signal-exit": "^4.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/yallist": { @@ -13627,6 +14022,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -13635,15 +14031,17 @@ } }, "node_modules/nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==", - "dev": true + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "dev": true, + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13653,15 +14051,20 @@ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13671,19 +14074,23 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -13698,6 +14105,7 @@ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -13712,6 +14120,7 @@ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -13730,6 +14139,7 @@ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -13739,30 +14149,15 @@ "node": ">= 0.4" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -13776,13 +14171,15 @@ "node_modules/oblivious-set": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz", - "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==" + "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==", + "license": "MIT" }, "node_modules/on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -13791,6 +14188,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -13800,6 +14198,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -13815,6 +14214,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -13834,11 +14234,30 @@ "dev": true, "license": "MIT" }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -13854,6 +14273,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -13869,15 +14289,24 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -13890,6 +14319,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -13904,12 +14334,13 @@ } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dev": true, + "license": "MIT", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -13920,6 +14351,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13928,6 +14360,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13936,13 +14369,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true + "dev": true, + "license": "(WTFPL OR MIT)" }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13951,37 +14386,38 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/path-to-regexp": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.1.0.tgz", - "integrity": "sha512-Bqn3vc8CMHty6zuD+tG23s6v2kwxslHEhTj4eYaVKGIEB+YX/2wd0/rgXLFD9G9id9KCtbVy/3ZgmvZjpa0UdQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "license": "MIT", "engines": { "node": ">=16" } @@ -13991,6 +14427,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13999,28 +14436,33 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -14031,6 +14473,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -14040,34 +14483,44 @@ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/pkg-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", - "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", "dev": true, + "license": "MIT", "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.6.1", - "pathe": "^1.1.2" + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" } }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "funding": [ { "type": "opencollective", @@ -14082,10 +14535,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -14105,6 +14559,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.13" }, @@ -14119,6 +14574,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -14143,6 +14599,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" @@ -14168,6 +14625,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { "@csstools/utilities": "^1.0.0", "postcss-value-parser": "^4.2.0" @@ -14183,6 +14641,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-8.0.2.tgz", "integrity": "sha512-xWf/JmAxVoB5bltHpXk+uGRoGFwu4WDAR7210el+iyvTdqiKpDhtcT8N3edXMoVJY0WHFMrKMUieql/wRNiXkw==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -14211,6 +14670,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.2", "@csstools/css-parser-algorithms": "^2.2.0", @@ -14225,9 +14685,9 @@ } }, "node_modules/postcss-custom-properties": { - "version": "13.3.8", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-13.3.8.tgz", - "integrity": "sha512-OP9yj4yXxYOiW2n2TRpnE7C0yePvBiZb72S22mZVNzZEObdTYFjNaX6oZO4R4E8Ie9RmC/Jxw8EKYSbLrC1EFA==", + "version": "13.3.12", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-13.3.12.tgz", + "integrity": "sha512-oPn/OVqONB2ZLNqN185LDyaVByELAA/u3l2CS2TS16x2j2XsmV4kd8U49+TMxmUsEU9d8fB/I10E6U7kB0L1BA==", "funding": [ { "type": "github", @@ -14238,10 +14698,11 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { - "@csstools/cascade-layer-name-parser": "^1.0.9", - "@csstools/css-parser-algorithms": "^2.6.1", - "@csstools/css-tokenizer": "^2.2.4", + "@csstools/cascade-layer-name-parser": "^1.0.13", + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1", "@csstools/utilities": "^1.0.0", "postcss-value-parser": "^4.2.0" }, @@ -14253,9 +14714,9 @@ } }, "node_modules/postcss-custom-selectors": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-7.1.8.tgz", - "integrity": "sha512-fqDkGSEsO7+oQaqdRdR8nwwqH+N2uk6LE/2g4myVJJYz/Ly418lHKEleKTdV/GzjBjFcG4n0dbfuH/Pd2BE8YA==", + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-7.1.12.tgz", + "integrity": "sha512-ctIoprBMJwByYMGjXG0F7IT2iMF2hnamQ+aWZETyBM0aAlyaYdVZTeUkk8RB+9h9wP+NdN3f01lfvKl2ZSqC0g==", "funding": [ { "type": "github", @@ -14266,11 +14727,12 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { - "@csstools/cascade-layer-name-parser": "^1.0.9", - "@csstools/css-parser-algorithms": "^2.6.1", - "@csstools/css-tokenizer": "^2.2.4", - "postcss-selector-parser": "^6.0.13" + "@csstools/cascade-layer-name-parser": "^1.0.13", + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1", + "postcss-selector-parser": "^6.1.0" }, "engines": { "node": "^14 || ^16 || >=18" @@ -14283,6 +14745,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-7.0.2.tgz", "integrity": "sha512-cMnslilYxBf9k3qejnovrUONZx1rXeUZJw06fgIUBzABJe3D2LiLL5WAER7Imt3nrkaIgG05XZBztueLEf5P8w==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -14311,6 +14774,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" @@ -14326,6 +14790,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "license": "MIT", "peerDependencies": { "postcss": "^8.1.4" } @@ -14334,6 +14799,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-8.0.2.tgz", "integrity": "sha512-f/Vd+EC/GaKElknU59esVcRYr/Y3t1ZAQyL4u2xSOgkDy4bMCmG7VP5cGvj3+BTLNE9ETfEuz2nnt4qkZwTTeA==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -14352,6 +14818,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-7.0.2.tgz", "integrity": "sha512-AHAJ89UQBcqBvFgQJE9XasGuwMNkKsGj4D/f9Uk60jFmEBHpAL14DrnSk3Rj+SwZTr/WUG+mh+Rvf8fid/346w==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -14370,6 +14837,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", "peerDependencies": { "postcss": "^8.1.0" } @@ -14378,6 +14846,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-4.0.1.tgz", "integrity": "sha512-V5OuQGw4lBumPlwHWk/PRfMKjaq/LTGR4WDTemIMCaMevArVfCCA9wBJiL1VjDAd+rzuCIlkRoRvDsSiAaZ4Fg==", + "license": "CC0-1.0", "engines": { "node": "^14 || ^16 || >=18" }, @@ -14393,6 +14862,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-5.0.2.tgz", "integrity": "sha512-Sszjwo0ubETX0Fi5MvpYzsONwrsjeabjMoc5YqHvURFItXgIu3HdCjcVuVKGMPGzKRhgaknmdM5uVWInWPJmeg==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -14412,6 +14882,7 @@ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -14428,6 +14899,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "license": "MIT", "peerDependencies": { "postcss": "^8.0.0" } @@ -14437,6 +14909,7 @@ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", "dev": true, + "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" }, @@ -14465,6 +14938,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", @@ -14493,6 +14967,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" @@ -14513,23 +14988,12 @@ } } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", - "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, + "license": "ISC", "bin": { "yaml": "bin.mjs" }, @@ -14551,6 +15015,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -14565,23 +15030,31 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } @@ -14600,6 +15073,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -14625,6 +15099,7 @@ "url": "https://liberapay.com/mrcgrtz" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" }, @@ -14636,6 +15111,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-4.0.1.tgz", "integrity": "sha512-HQZ0qi/9iSYHW4w3ogNqVNr2J49DHJAl7r8O2p0Meip38jsdnRPgiDW7r/LlLrrMBMe3KHkvNtAV2UmRVxzLIg==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -14654,6 +15130,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", "peerDependencies": { "postcss": "^8" } @@ -14662,6 +15139,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-8.0.1.tgz", "integrity": "sha512-Ow2LedN8sL4pq8ubukO77phSVt4QyCm35ZGCYXKvRFayAwcpgB0sjNJglDoTuRdUL32q/ZC1VkPBo0AOEr4Uiw==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -14690,6 +15168,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-cascade-layers": "^3.0.1", "@csstools/postcss-color-function": "^2.2.3", @@ -14759,6 +15238,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-8.0.2.tgz", "integrity": "sha512-FYTIuRE07jZ2CW8POvctRgArQJ43yxhr5vLmImdKUvjFCkR09kh8pIdlCwdx/jbFm7MiW4QP58L4oOUv3grQYA==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -14777,21 +15257,24 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "license": "MIT", "peerDependencies": { "postcss": "^8.0.3" } }, "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", - "dev": true + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", + "dev": true, + "license": "MIT" }, "node_modules/postcss-safe-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.0" }, @@ -14822,6 +15305,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "engines": { "node": ">=12.0" }, @@ -14843,6 +15327,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.13" }, @@ -14854,9 +15339,10 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -14868,13 +15354,15 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -14884,6 +15372,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -14899,6 +15388,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -14913,6 +15403,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -14924,6 +15415,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -14933,14 +15425,16 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" }, "node_modules/protobufjs": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", - "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", "dev": true, "hasInstallScript": true, + "license": "BSD-3-Clause", "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -14961,10 +15455,11 @@ } }, "node_modules/protobufjs-cli": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.1.2.tgz", - "integrity": "sha512-8ivXWxT39gZN4mm4ArQyJrRgnIwZqffBWoLDsE21TmMcKI3XwJMV4lEF2WU02C4JAtgYYc2SfJIltelD8to35g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.1.3.tgz", + "integrity": "sha512-MqD10lqF+FMsOayFiNOdOGNlXc4iKDCf0ZQPkPR+gizYh9gqUeGTWulABUCdI+N67w5RfJ6xhgX4J8pa8qmMXQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "chalk": "^4.0.0", "escodegen": "^1.13.0", @@ -14993,6 +15488,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^4.2.0", @@ -15015,6 +15511,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -15024,6 +15521,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -15032,23 +15530,12 @@ "node": ">= 0.8.0" } }, - "node_modules/protobufjs-cli/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/protobufjs-cli/node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -15071,13 +15558,11 @@ } }, "node_modules/protobufjs-cli/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -15085,20 +15570,12 @@ "node": ">=10" } }, - "node_modules/protobufjs-cli/node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "engines": { - "node": ">=14.14" - } - }, "node_modules/protobufjs-cli/node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2" }, @@ -15106,37 +15583,54 @@ "node": ">= 0.8.0" } }, - "node_modules/protobufjs-cli/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, "node_modules/query-string": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "license": "MIT", "dependencies": { "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", @@ -15154,7 +15648,8 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -15174,13 +15669,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -15190,6 +15687,7 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -15199,6 +15697,7 @@ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -15214,6 +15713,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -15222,6 +15722,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -15230,10 +15731,23 @@ "node": ">=0.10.0" } }, + "node_modules/react-base16-styling": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.10.0.tgz", + "integrity": "sha512-H1k2eFB6M45OaiRru3PBXkuCcn2qNmx+gzLb4a9IPMR7tMH8oBRXU5jGbPDYG1Hz+82d88ED0vjR8BmqU3pQdg==", + "license": "MIT", + "dependencies": { + "@types/lodash": "^4.17.0", + "color": "^4.2.3", + "csstype": "^3.1.3", + "lodash-es": "^4.17.21" + } + }, "node_modules/react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -15248,6 +15762,7 @@ "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5" }, @@ -15264,6 +15779,7 @@ "resolved": "https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz", "integrity": "sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ==", "deprecated": "react-flow-renderer has been renamed to reactflow, please use this package from now on https://reactflow.dev/docs/guides/migrate-to-v11/", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.9", "@types/d3": "^7.4.0", @@ -15285,12 +15801,28 @@ "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" + }, + "node_modules/react-json-tree": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.19.0.tgz", + "integrity": "sha512-PqT1WRVcWP+RROsZPQfNEKIC1iM/ZMfY4g5jN6oDnXp5593PPRAYgoHcgYCDjflAHQMtxl8XGdlTwIBdEGUXvw==", + "license": "MIT", + "dependencies": { + "@types/lodash": "^4.17.0", + "react-base16-styling": "^0.10.0" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } }, "node_modules/react-query": { "version": "3.39.3", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", "broadcast-channel": "^3.4.1", @@ -15317,6 +15849,7 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -15325,12 +15858,13 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", "hoist-non-react-statics": "^3.1.0", "loose-envify": "^1.3.1", - "path-to-regexp": "^1.9.0", + "path-to-regexp": "^1.7.0", "prop-types": "^15.6.2", "react-is": "^16.6.0", "tiny-invariant": "^1.0.2", @@ -15344,6 +15878,7 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -15361,6 +15896,7 @@ "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2", "loose-envify": "^1.2.0", @@ -15374,6 +15910,7 @@ "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2", "loose-envify": "^1.2.0", @@ -15386,12 +15923,14 @@ "node_modules/react-router/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" }, "node_modules/react-router/node_modules/path-to-regexp": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", "dependencies": { "isarray": "0.0.1" } @@ -15399,12 +15938,14 @@ "node_modules/react-router/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" }, "node_modules/react-tiny-popover": { "version": "6.0.10", "resolved": "https://registry.npmjs.org/react-tiny-popover/-/react-tiny-popover-6.0.10.tgz", "integrity": "sha512-ECMucd701SxWHGa+2YuVvccCxxTjmhomcD0ZYTF+Qmi5qNAj8pdlExFN+k+p1G78QTYIGPGNLocxRb9f6cZ0Mw==", + "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0", "react-dom": "^16.8.0 || ^17.0.0" @@ -15414,6 +15955,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.2.0.tgz", "integrity": "sha512-Pg2Ju7NngAamarFvLwqrFomJ57u/Ay6i6zfLurt/qPynWkAkOthu6vxfqYpJCyNhHRhR4hu7+bySSeWWJu6PAg==", + "license": "MIT", "dependencies": { "clsx": "^1.1.1" }, @@ -15427,6 +15969,7 @@ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^2.3.0" } @@ -15436,6 +15979,7 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, + "license": "MIT", "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", @@ -15451,6 +15995,7 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", @@ -15468,6 +16013,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -15481,6 +16027,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -15493,6 +16040,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -15508,6 +16056,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -15520,6 +16069,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } @@ -15528,13 +16078,15 @@ "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -15547,6 +16099,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } @@ -15556,19 +16109,22 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "license": "MIT", "engines": { - "node": ">=8.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/redent": { @@ -15576,6 +16132,7 @@ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, + "license": "MIT", "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" @@ -15585,18 +16142,20 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -15609,13 +16168,15 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -15626,27 +16187,32 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -15656,15 +16222,16 @@ } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -15677,6 +16244,7 @@ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, + "license": "MIT", "dependencies": { "rc": "^1.1.6", "safe-buffer": "^5.0.1" @@ -15687,6 +16255,7 @@ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", "dev": true, + "license": "MIT", "dependencies": { "rc": "^1.0.1" }, @@ -15694,37 +16263,51 @@ "node": ">=0.10.0" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, "node_modules/remove-accents": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", - "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -15734,6 +16317,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -15742,30 +16326,36 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/requizzle": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.21" } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -15775,6 +16365,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15782,13 +16373,15 @@ "node_modules/resolve-pathname": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "license": "MIT" }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -15798,6 +16391,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -15812,6 +16407,8 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15830,7 +16427,8 @@ "node_modules/robust-predicates": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" }, "node_modules/rollup": { "version": "3.29.5", @@ -15853,7 +16451,8 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/run-parallel": { "version": "1.2.0", @@ -15874,6 +16473,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -15881,17 +16481,20 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -15905,17 +16508,36 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -15927,15 +16549,17 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sass": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz", - "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==", + "version": "1.83.4", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.4.tgz", + "integrity": "sha512-B1bozCeNQiOgDcLd33e2Cs2U60wZwjUUXzh900ZyQF5qUasvMdDZYbQ566LJu7cqR+sAHlAfO6RMkaID5s6qpA==", + "license": "MIT", "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -15943,6 +16567,9 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/saxes": { @@ -15950,6 +16577,7 @@ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, + "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, @@ -15961,6 +16589,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -15971,15 +16600,17 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/serve": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.3.tgz", - "integrity": "sha512-VqUFMC7K3LDGeGnJM9h56D3XGKb6KGgOw0cVNtA26yYXHCcpxf3xwCTUaQoWlVS7i8Jdh3GjQkOB23qsXyjoyQ==", + "version": "14.2.4", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.4.tgz", + "integrity": "sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==", "dev": true, + "license": "MIT", "dependencies": { "@zeit/schemas": "2.36.0", "ajv": "8.12.0", @@ -15990,7 +16621,7 @@ "clipboardy": "3.0.0", "compression": "1.7.4", "is-port-reachable": "4.0.0", - "serve-handler": "6.1.5", + "serve-handler": "6.1.6", "update-check": "1.5.4" }, "bin": { @@ -16001,18 +16632,18 @@ } }, "node_modules/serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", "mime-types": "2.1.18", "minimatch": "3.1.2", "path-is-inside": "1.0.2", - "path-to-regexp": "^3.3.0", + "path-to-regexp": "3.3.0", "range-parser": "1.2.0" } }, @@ -16021,6 +16652,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -16030,6 +16662,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "~1.33.0" }, @@ -16041,13 +16674,15 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/serve/node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16064,6 +16699,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -16075,13 +16711,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -16099,6 +16737,7 @@ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -16109,11 +16748,27 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -16126,20 +16781,79 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -16152,18 +16866,36 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -16173,6 +16905,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -16190,14 +16923,16 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -16207,6 +16942,7 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -16216,28 +16952,32 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true + "dev": true, + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", - "dev": true + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" }, "node_modules/split-on-first": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "license": "MIT", "engines": { "node": ">=6" } @@ -16246,6 +16986,7 @@ "version": "2.0.10", "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "license": "MIT", "dependencies": { "stackframe": "^1.3.4" } @@ -16254,6 +16995,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -16265,6 +17007,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", "engines": { "node": ">=8" } @@ -16273,12 +17016,14 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", @@ -16291,10 +17036,11 @@ } }, "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "dev": true, + "license": "MIT" }, "node_modules/strict-event-emitter": { "version": "0.5.1", @@ -16307,6 +17053,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "license": "MIT", "engines": { "node": ">=4" } @@ -16315,20 +17062,25 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width-cjs": { @@ -16337,6 +17089,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -16350,32 +17103,73 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -16384,16 +17178,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -16403,15 +17212,20 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -16421,6 +17235,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -16438,6 +17253,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -16451,6 +17267,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -16463,6 +17280,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -16472,6 +17290,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -16481,6 +17300,7 @@ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.0" }, @@ -16493,6 +17313,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -16505,6 +17326,7 @@ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.10.0" }, @@ -16516,13 +17338,15 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/stylelint": { "version": "14.16.1", "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.1.tgz", "integrity": "sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A==", "dev": true, + "license": "MIT", "dependencies": { "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", @@ -16579,6 +17403,7 @@ "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.5.tgz", "integrity": "sha512-U44lELgLZhbAD/xy/vncZ2Pq8sh2TnpiPvo38Ifg9+zeioR+LAkHu0i6YORIOxFafZoVg0xqQwex6e6F25S5XA==", "dev": true, + "license": "MIT", "bin": { "stylelint-config-prettier": "bin/check.js", "stylelint-config-prettier-check": "bin/check.js" @@ -16595,6 +17420,7 @@ "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz", "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==", "dev": true, + "license": "MIT", "peerDependencies": { "stylelint": "^14.0.0" } @@ -16604,6 +17430,7 @@ "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-5.0.2.tgz", "integrity": "sha512-b14BSZjcwW0hqbzm9b0S/ScN2+3CO3O4vcMNOw2KGf8lfVSwJ4p5TbNEXKwKl1+0FMtgRXZj6DqVUe/7nGnuBg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-scss": "^4.0.2", "stylelint-config-recommended": "^6.0.0", @@ -16618,6 +17445,7 @@ "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-24.0.0.tgz", "integrity": "sha512-+RtU7fbNT+VlNbdXJvnjc3USNPZRiRVp/d2DxOF/vBDDTi0kH5RX2Ny6errdtZJH3boO+bmqIYEllEmok4jiuw==", "dev": true, + "license": "MIT", "dependencies": { "stylelint-config-recommended": "^6.0.0" }, @@ -16630,6 +17458,7 @@ "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-3.0.0.tgz", "integrity": "sha512-zt3ZbzIbllN1iCmc94e4pDxqpkzeR6CJo5DDXzltshuXr+82B8ylHyMMARNnUYrZH80B7wgY7UkKTYCFM0UUyw==", "dev": true, + "license": "MIT", "dependencies": { "stylelint-config-recommended-scss": "^5.0.2", "stylelint-config-standard": "^24.0.0" @@ -16643,6 +17472,7 @@ "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.7.0.tgz", "integrity": "sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", @@ -16657,13 +17487,37 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" }, "node_modules/stylelint/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { "node": ">=8" } @@ -16673,6 +17527,7 @@ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -16695,6 +17550,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -16704,37 +17560,38 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/sucrase/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -16749,6 +17606,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -16761,6 +17619,7 @@ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -16774,6 +17633,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -16785,7 +17645,8 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/svg-tags": { "version": "1.0.0", @@ -16794,9 +17655,10 @@ "dev": true }, "node_modules/svgo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", - "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "license": "MIT", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", @@ -16821,13 +17683,15 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -16840,55 +17704,80 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, "node_modules/tailwindcss": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", - "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "dev": true, + "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -16898,17 +17787,83 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tailwindcss/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tailwindcss/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -16918,6 +17873,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -16928,24 +17884,28 @@ "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" }, "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", - "dev": true + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" }, "node_modules/tinypool": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.4.0.tgz", "integrity": "sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -16955,17 +17915,19 @@ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.1.1.tgz", "integrity": "sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -16985,6 +17947,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -16995,20 +17958,12 @@ "node": ">=6" } }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/tr46": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dev": true, + "license": "MIT", "dependencies": { "punycode": "^2.3.0" }, @@ -17016,20 +17971,12 @@ "node": ">=14" } }, - "node_modules/tr46/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -17038,13 +17985,15 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -17057,6 +18006,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -17065,15 +18015,17 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -17088,13 +18040,15 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -17103,18 +18057,19 @@ } }, "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.33.0.tgz", + "integrity": "sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -17125,30 +18080,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -17158,17 +18115,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -17178,17 +18137,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -17198,10 +18158,11 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -17211,22 +18172,25 @@ } }, "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" }, "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", - "dev": true + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "dev": true, + "license": "MIT" }, "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, + "license": "BSD-2-Clause", "bin": { "uglifyjs": "bin/uglifyjs" }, @@ -17235,39 +18199,45 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/underscore": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", - "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", - "dev": true + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "dev": true, + "license": "MIT" }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true, "license": "MIT", "peer": true }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -17277,6 +18247,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -17286,10 +18257,11 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -17299,6 +18271,7 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -17308,6 +18281,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } @@ -17316,15 +18290,16 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.6.2", "detect-node": "^2.0.4" } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "funding": [ { "type": "opencollective", @@ -17339,9 +18314,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -17355,6 +18331,7 @@ "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==", "dev": true, + "license": "MIT", "dependencies": { "registry-auth-token": "3.3.2", "registry-url": "3.1.0" @@ -17365,24 +18342,17 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -17391,19 +18361,22 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/v8-compile-cache": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -17412,27 +18385,29 @@ "node_modules/value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "license": "MIT" }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/vite": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", - "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", + "version": "4.5.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.9.tgz", + "integrity": "sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", - "rollup": "^3.29.5" + "rollup": "^3.27.1" }, "bin": { "vite": "bin/vite.js" @@ -17484,13 +18459,14 @@ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.29.8.tgz", "integrity": "sha512-b6OtCXfk65L6SElVM20q5G546yu10/kNrhg08afEoWlFRJXFq9/6glsvSVY+aI6YeC1tu2TtAqI2jHEQmOmsFw==", "dev": true, + "license": "MIT", "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", "mlly": "^1.1.0", "pathe": "^1.1.0", "picocolors": "^1.0.0", - "vite": "^4.5.4" + "vite": "^3.0.0 || ^4.0.0" }, "bin": { "vite-node": "vite-node.mjs" @@ -17507,14 +18483,15 @@ "resolved": "https://registry.npmjs.org/vite-plugin-eslint/-/vite-plugin-eslint-1.8.1.tgz", "integrity": "sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^4.2.1", "@types/eslint": "^8.4.5", - "rollup": "^3.29.5" + "rollup": "^2.77.2" }, "peerDependencies": { "eslint": ">=7", - "vite": ">=4.5.4" + "vite": ">=2" } }, "node_modules/vite-plugin-eslint/node_modules/@rollup/pluginutils": { @@ -17522,6 +18499,7 @@ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", "dev": true, + "license": "MIT", "dependencies": { "estree-walker": "^2.0.1", "picomatch": "^2.2.2" @@ -17530,17 +18508,47 @@ "node": ">= 8.0.0" } }, + "node_modules/vite-plugin-eslint/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vite-plugin-eslint/node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/vite-plugin-svgr": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-2.4.0.tgz", "integrity": "sha512-q+mJJol6ThvqkkJvvVFEndI4EaKIjSI0I3jNFgSoC9fXAz1M7kYTVUin8fhUsFojFDKZ9VHKtX6NXNaOLpbsHA==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.2", "@svgr/core": "^6.5.1" }, "peerDependencies": { - "vite": "^4.5.4" + "vite": "^2.6.0 || 3 || 4" } }, "node_modules/vitest": { @@ -17548,6 +18556,7 @@ "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.29.8.tgz", "integrity": "sha512-JIAVi2GK5cvA6awGpH0HvH/gEG9PZ0a/WoxdiV3PmqK+3CjQMf8c+J/Vhv4mdZ2nRyXFw66sAg6qz7VNkaHfDQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/chai": "^4.3.4", "@types/chai-subset": "^1.3.3", @@ -17570,7 +18579,7 @@ "tinybench": "^2.3.1", "tinypool": "^0.4.0", "tinyspy": "^1.0.2", - "vite": "^4.5.4", + "vite": "^3.0.0 || ^4.0.0", "vite-node": "0.29.8", "why-is-node-running": "^2.2.2" }, @@ -17625,6 +18634,7 @@ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, + "license": "MIT", "dependencies": { "xml-name-validator": "^4.0.0" }, @@ -17635,13 +18645,15 @@ "node_modules/web-vitals": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", - "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==" + "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==", + "license": "Apache-2.0" }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" } @@ -17651,6 +18663,7 @@ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", "dev": true, + "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" }, @@ -17658,23 +18671,12 @@ "node": ">=12" } }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" } @@ -17684,6 +18686,7 @@ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, + "license": "MIT", "dependencies": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" @@ -17697,6 +18700,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -17708,39 +18712,45 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, + "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, + "license": "MIT", "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", + "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -17754,6 +18764,7 @@ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, + "license": "MIT", "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -17768,15 +18779,17 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "for-each": "^0.3.3", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -17787,10 +18800,11 @@ } }, "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, + "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -17807,6 +18821,7 @@ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", "dev": true, + "license": "MIT", "dependencies": { "string-width": "^5.0.1" }, @@ -17817,102 +18832,129 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/widest-line/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/widest-line/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/widest-line/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -17926,6 +18968,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -17947,6 +18990,7 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12" } @@ -17955,19 +18999,22 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/xmlcreate": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -17976,13 +19023,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 6" } @@ -17992,6 +19041,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -18010,15 +19060,39 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yargs/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -18028,6 +19102,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -18052,6 +19127,7 @@ "version": "3.7.2", "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "license": "MIT", "engines": { "node": ">=12.7.0" }, diff --git a/web/vtadmin/package.json b/web/vtadmin/package.json index 5d4d5dc787a..be7b819ede9 100644 --- a/web/vtadmin/package.json +++ b/web/vtadmin/package.json @@ -3,8 +3,8 @@ "version": "0.1.0", "private": true, "engines": { - "node": ">=20.12.0", - "npm": ">=10.5.0" + "node": ">=22.13.0", + "npm": ">=10.9.2" }, "dependencies": { "@bugsnag/js": "^7.20.0", @@ -17,7 +17,6 @@ "d3": "^7.9.0", "dayjs": "^1.11.7", "downshift": "^7.2.0", - "highcharts-react-official": "^3.1.0", "history": "^5.3.0", "lodash-es": "^4.17.21", "path-to-regexp": "^8.1.0", @@ -27,6 +26,7 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-flow-renderer": "^10.3.17", + "react-json-tree": "^0.19.0", "react-query": "^3.5.9", "react-router-dom": "^5.3.4", "react-tiny-popover": "^6.0.5", @@ -74,7 +74,7 @@ ] }, "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.1", + "@rollup/plugin-commonjs": "^28.0.2", "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.5", "@testing-library/react-hooks": "^5.0.3", @@ -90,17 +90,17 @@ "i": "^0.3.7", "jsdom": "^21.1.1", "msw": "^2.5.2", - "npm": "^10.8.0", + "npm": "^10.9.2", "postcss": "^8.4.31", "prettier": "^2.2.1", - "protobufjs-cli": "^1.1.1", + "protobufjs-cli": "^1.1.3", "serve": "^14.2.0", "stylelint": "^14.4.0", "stylelint-config-prettier": "^9.0.3", "stylelint-config-standard-scss": "^3.0.0", "tailwindcss": "^3.0.18", "typescript": "^5.0.2", - "vite": "^4.5.3", + "vite": "^4.5.6", "vite-plugin-eslint": "^1.8.1", "vite-plugin-svgr": "^2.4.0", "vitest": "^0.29.8" diff --git a/web/vtadmin/src/components/App.tsx b/web/vtadmin/src/components/App.tsx index 3bb41ea35f0..fd0f772ae19 100644 --- a/web/vtadmin/src/components/App.tsx +++ b/web/vtadmin/src/components/App.tsx @@ -45,6 +45,7 @@ import { Transactions } from './routes/Transactions'; import { Transaction } from './routes/transaction/Transaction'; import { CreateReshard } from './routes/createWorkflow/CreateReshard'; import { CreateMaterialize } from './routes/createWorkflow/CreateMaterialize'; +import { TopologyTree } from './routes/topologyTree/TopologyTree'; import { SchemaMigrations } from './routes/SchemaMigrations'; import { CreateSchemaMigration } from './routes/createSchemaMigration/CreateSchemaMigration'; @@ -164,6 +165,10 @@ export const App = () => { + + + + diff --git a/web/vtadmin/src/components/jsonViewTree/JSONViewTree.tsx b/web/vtadmin/src/components/jsonViewTree/JSONViewTree.tsx new file mode 100644 index 00000000000..af4e71db38a --- /dev/null +++ b/web/vtadmin/src/components/jsonViewTree/JSONViewTree.tsx @@ -0,0 +1,95 @@ +/** + * Copyright 2025 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. + */ + +import React, { useState } from 'react'; +import { JSONTree } from 'react-json-tree'; + +const vtAdminTheme = { + scheme: 'vtadmin', + author: 'custom', + base00: '#ffffff', + base01: '#f6f8fa', + base02: '#e6e8eb', + base03: '#8c8c8c', + base04: '#3c3c3c', + base05: '#2c2c2c', + base06: '#0057b8', + base07: '#000000', + base08: '#00875a', + base09: '#2c2c2c', + base0A: '#e44d26', + base0B: '#2c2c2c', + base0C: '#1a73e8', + base0D: '#3d5afe', + base0E: '#3cba54', + base0F: '#ff6f61', +}; + +interface JSONViewTreeProps { + data: any; +} + +const JSONViewTree: React.FC = ({ data }) => { + const [expandAll, setExpandAll] = useState(false); + const [treeKey, setTreeKey] = useState(0); + + const handleExpand = () => { + setExpandAll(true); + setTreeKey((prev) => prev + 1); + }; + + const handleCollapse = () => { + setExpandAll(false); + setTreeKey((prev) => prev + 1); + }; + + const getItemString = (type: string, data: any) => { + if (Array.isArray(data)) { + return `${type}[${data.length}]`; + } + return type; + }; + + if (!data) return null; + return ( +
+
+ + +
+ expandAll} + /> +
+ ); +}; + +export default JSONViewTree; diff --git a/web/vtadmin/src/components/routes/keyspace/Keyspace.tsx b/web/vtadmin/src/components/routes/keyspace/Keyspace.tsx index 61bf52bb189..068f9cea2cd 100644 --- a/web/vtadmin/src/components/routes/keyspace/Keyspace.tsx +++ b/web/vtadmin/src/components/routes/keyspace/Keyspace.tsx @@ -19,7 +19,6 @@ import { Link, Redirect, Route } from 'react-router-dom'; import { useKeyspace } from '../../../hooks/api'; import { useDocumentTitle } from '../../../hooks/useDocumentTitle'; import { isReadOnlyMode } from '../../../util/env'; -import { Code } from '../../Code'; import { ContentContainer } from '../../layout/ContentContainer'; import { NavCrumbs } from '../../layout/NavCrumbs'; import { WorkspaceHeader } from '../../layout/WorkspaceHeader'; @@ -32,6 +31,8 @@ import { Advanced } from './Advanced'; import style from './Keyspace.module.scss'; import { KeyspaceShards } from './KeyspaceShards'; import { KeyspaceVSchema } from './KeyspaceVSchema'; +import JSONViewTree from '../../jsonViewTree/JSONViewTree'; +import { Code } from '../../Code'; interface RouteParams { clusterID: string; @@ -94,6 +95,7 @@ export const Keyspace = () => { + @@ -114,6 +116,11 @@ export const Keyspace = () => { + + + + + {!isReadOnlyMode() && ( diff --git a/web/vtadmin/src/components/routes/keyspaces/KeyspaceActions.tsx b/web/vtadmin/src/components/routes/keyspaces/KeyspaceActions.tsx index 6b123258d3c..4a8c83a5fe2 100644 --- a/web/vtadmin/src/components/routes/keyspaces/KeyspaceActions.tsx +++ b/web/vtadmin/src/components/routes/keyspaces/KeyspaceActions.tsx @@ -79,8 +79,8 @@ const KeyspaceActions: React.FC = ({ keyspace, clusterID } isOpen={currentDialog === 'Validate Schema'} body={
- Validates that the schema on the primary tablet for shard 0 matches the schema on all of the - other tablets in the keyspace {keyspace}. + Validates that the schema on the primary tablet for the first shard matches the schema on all of + the other tablets in the keyspace {keyspace}.
} successBody={ diff --git a/web/vtadmin/src/components/routes/shard/Shard.tsx b/web/vtadmin/src/components/routes/shard/Shard.tsx index 686dc089d8f..8f713be9b13 100644 --- a/web/vtadmin/src/components/routes/shard/Shard.tsx +++ b/web/vtadmin/src/components/routes/shard/Shard.tsx @@ -24,12 +24,13 @@ import { WorkspaceTitle } from '../../layout/WorkspaceTitle'; import { ContentContainer } from '../../layout/ContentContainer'; import { Tab } from '../../tabs/Tab'; import { TabContainer } from '../../tabs/TabContainer'; -import { Code } from '../../Code'; import { useDocumentTitle } from '../../../hooks/useDocumentTitle'; import { KeyspaceLink } from '../../links/KeyspaceLink'; import { useKeyspace } from '../../../hooks/api'; import { ShardTablets } from './ShardTablets'; import Advanced from './Advanced'; +import JSONViewTree from '../../jsonViewTree/JSONViewTree'; +import { Code } from '../../Code'; interface RouteParams { clusterID: string; @@ -114,6 +115,7 @@ export const Shard = () => { + @@ -123,6 +125,7 @@ export const Shard = () => {
{shard && } + {shard && } diff --git a/web/vtadmin/src/components/routes/stream/Stream.tsx b/web/vtadmin/src/components/routes/stream/Stream.tsx index 45e9846315a..6143ac3e302 100644 --- a/web/vtadmin/src/components/routes/stream/Stream.tsx +++ b/web/vtadmin/src/components/routes/stream/Stream.tsx @@ -13,17 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Link, useParams } from 'react-router-dom'; +import { Link, Redirect, Route, Switch, useParams, useRouteMatch } from 'react-router-dom'; import { useWorkflow } from '../../../hooks/api'; import { useDocumentTitle } from '../../../hooks/useDocumentTitle'; import { formatStreamKey, getStream } from '../../../util/workflows'; -import { Code } from '../../Code'; import { ContentContainer } from '../../layout/ContentContainer'; import { NavCrumbs } from '../../layout/NavCrumbs'; import { WorkspaceHeader } from '../../layout/WorkspaceHeader'; import { WorkspaceTitle } from '../../layout/WorkspaceTitle'; import style from './Stream.module.scss'; +import JSONViewTree from '../../jsonViewTree/JSONViewTree'; +import { TabContainer } from '../../tabs/TabContainer'; +import { Tab } from '../../tabs/Tab'; +import { Code } from '../../Code'; interface RouteParams { clusterID: string; @@ -36,6 +39,7 @@ interface RouteParams { export const Stream = () => { const params = useParams(); + const { path, url } = useRouteMatch(); const { data: workflow } = useWorkflow({ clusterID: params.clusterID, keyspace: params.keyspace, @@ -72,7 +76,17 @@ export const Stream = () => { - + + + + + + + {stream && } + {stream && } + + + ); diff --git a/web/vtadmin/src/components/routes/tablet/Tablet.tsx b/web/vtadmin/src/components/routes/tablet/Tablet.tsx index b0181251fd0..f4a9ca20248 100644 --- a/web/vtadmin/src/components/routes/tablet/Tablet.tsx +++ b/web/vtadmin/src/components/routes/tablet/Tablet.tsx @@ -19,7 +19,6 @@ import { useExperimentalTabletDebugVars, useTablet } from '../../../hooks/api'; import { useDocumentTitle } from '../../../hooks/useDocumentTitle'; import { isReadOnlyMode } from '../../../util/env'; import { formatDisplayType, formatState } from '../../../util/tablets'; -import { Code } from '../../Code'; import { ContentContainer } from '../../layout/ContentContainer'; import { NavCrumbs } from '../../layout/NavCrumbs'; import { WorkspaceHeader } from '../../layout/WorkspaceHeader'; @@ -34,6 +33,8 @@ import style from './Tablet.module.scss'; import { TabletCharts } from './TabletCharts'; import { env } from '../../../util/env'; import FullStatus from './FullStatus'; +import JSONViewTree from '../../jsonViewTree/JSONViewTree'; +import { Code } from '../../Code'; interface RouteParams { alias: string; @@ -108,6 +109,7 @@ export const Tablet = () => { + @@ -128,6 +130,14 @@ export const Tablet = () => { + +
+ + + {env().VITE_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS && } +
+
+ {tablet && } {!isReadOnlyMode() && ( diff --git a/web/vtadmin/src/components/routes/topology/Topology.tsx b/web/vtadmin/src/components/routes/topology/Topology.tsx index b4a65c3e8df..bd08dcfd1b1 100644 --- a/web/vtadmin/src/components/routes/topology/Topology.tsx +++ b/web/vtadmin/src/components/routes/topology/Topology.tsx @@ -53,6 +53,11 @@ export const Topology = () => { View Topology + + + View Topology Tree + + )); @@ -65,7 +70,11 @@ export const Topology = () => {
Clusters
- +
diff --git a/web/vtadmin/src/components/routes/topologyTree/Node.tsx b/web/vtadmin/src/components/routes/topologyTree/Node.tsx new file mode 100644 index 00000000000..4bb70ddbe0e --- /dev/null +++ b/web/vtadmin/src/components/routes/topologyTree/Node.tsx @@ -0,0 +1,74 @@ +/** + * 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. + */ +import React, { useEffect, useState } from 'react'; + +import { useTopologyPath } from '../../../hooks/api'; +import { buildChildNodes, TopologyNode } from './TopologyTree'; + +interface NodeParams { + topologyNode: TopologyNode; + clusterID: string; +} + +export const Node = ({ topologyNode, clusterID }: NodeParams) => { + const [isOpen, setIsOpen] = useState(false); + const [node, setNode] = useState(topologyNode); + + const childrenPath = `${topologyNode.path}/${topologyNode.name}`; + const { data } = useTopologyPath( + { clusterID, path: childrenPath }, + { + enabled: isOpen, + } + ); + + useEffect(() => { + if (data) { + setNode((prevNode) => ({ + ...prevNode, + children: buildChildNodes(data.cell, childrenPath), + data: data.cell?.data, + })); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [data]); + + const nodeTitle = `${isOpen ? '▼' : '►'} ${node.name}`; + return ( +
+
setIsOpen(!isOpen)}> + {nodeTitle} +
+ + {isOpen && ( +
+ {node.data ? ( +
+ {node.data} +
+ ) : ( + <> + {node.children && + node.children.map((child, idx) => { + return ; + })} + + )} +
+ )} +
+ ); +}; diff --git a/web/vtadmin/src/components/routes/topologyTree/TopologyTree.tsx b/web/vtadmin/src/components/routes/topologyTree/TopologyTree.tsx new file mode 100644 index 00000000000..cb27876391e --- /dev/null +++ b/web/vtadmin/src/components/routes/topologyTree/TopologyTree.tsx @@ -0,0 +1,103 @@ +/** + * 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. + */ +import React, { useEffect, useState } from 'react'; + +import { useTopologyPath } from '../../../hooks/api'; +import { useDocumentTitle } from '../../../hooks/useDocumentTitle'; +import { ContentContainer } from '../../layout/ContentContainer'; +import { NavCrumbs } from '../../layout/NavCrumbs'; +import { WorkspaceHeader } from '../../layout/WorkspaceHeader'; +import { WorkspaceTitle } from '../../layout/WorkspaceTitle'; +import { Link, useParams } from 'react-router-dom'; + +import { Node } from './Node'; +import { vtctldata } from '../../../proto/vtadmin'; + +export interface TopologyNode { + name?: string | null; + data?: string | null; + path: string; + children?: TopologyNode[]; +} + +export const buildChildNodes = (cell: vtctldata.ITopologyCell | null | undefined, path: string) => { + if (cell) { + const childNodes: TopologyNode[] | undefined = cell.children + ? cell.children.map((child) => { + return { + name: child, + path, + }; + }) + : undefined; + return childNodes; + } +}; + +export const TopologyTree = () => { + interface RouteParams { + clusterID: string; + } + useDocumentTitle('Cluster Topolgy'); + const { clusterID } = useParams(); + const { data } = useTopologyPath({ clusterID, path: '/' }); + const [topologyNode, setTopologyNode] = useState(); + + useEffect(() => { + if (data?.cell) { + const topologyNode: TopologyNode = { + path: data.cell.path || '/', + data: data.cell.data, + children: buildChildNodes(data.cell, ''), + }; + setTopologyNode(topologyNode); + } + }, [data]); + + if (!data) { + return ( +
+ + + Topology + + + {clusterID} + + + 404 +
+ ); + } + + return ( +
+ + + Topology + + {clusterID} + + + + {topologyNode && + topologyNode.children?.map((child, idx) => ( + + ))} + +
+ ); +}; diff --git a/web/vtadmin/src/components/routes/workflow/Workflow.tsx b/web/vtadmin/src/components/routes/workflow/Workflow.tsx index 939d1c6d386..7b3f0df32a5 100644 --- a/web/vtadmin/src/components/routes/workflow/Workflow.tsx +++ b/web/vtadmin/src/components/routes/workflow/Workflow.tsx @@ -30,11 +30,12 @@ import { ContentContainer } from '../../layout/ContentContainer'; import { TabContainer } from '../../tabs/TabContainer'; import { Tab } from '../../tabs/Tab'; import { getStreams } from '../../../util/workflows'; -import { Code } from '../../Code'; import { ShardLink } from '../../links/ShardLink'; import { WorkflowVDiff } from './WorkflowVDiff'; import { Select } from '../../inputs/Select'; import { formatDateTimeShort } from '../../../util/time'; +import JSONViewTree from '../../jsonViewTree/JSONViewTree'; +import { Code } from '../../Code'; interface RouteParams { clusterID: string; @@ -168,6 +169,7 @@ export const Workflow = () => { + @@ -192,6 +194,10 @@ export const Workflow = () => { + + + + diff --git a/web/vtadmin/src/hooks/api.ts b/web/vtadmin/src/hooks/api.ts index 18ab3b60a53..c2e1209f128 100644 --- a/web/vtadmin/src/hooks/api.ts +++ b/web/vtadmin/src/hooks/api.ts @@ -729,7 +729,7 @@ export const useTopologyPath = ( params: GetTopologyPathParams, options?: UseQueryOptions | undefined ) => { - return useQuery(['topology-path', params], () => getTopologyPath(params)); + return useQuery(['topology-path', params], () => getTopologyPath(params), options); }; /** * useValidate is a mutate hook that validates that all nodes reachable from the global replication graph, diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index fa47957e857..cc4fbfac9e1 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -26590,9 +26590,6 @@ export namespace tabletmanagerdata { /** ReplicationStatusResponse status */ status?: (replicationdata.IStatus|null); - - /** ReplicationStatusResponse backup_running */ - backup_running?: (boolean|null); } /** Represents a ReplicationStatusResponse. */ @@ -26607,9 +26604,6 @@ export namespace tabletmanagerdata { /** ReplicationStatusResponse status. */ public status?: (replicationdata.IStatus|null); - /** ReplicationStatusResponse backup_running. */ - public backup_running: boolean; - /** * Creates a new ReplicationStatusResponse instance using the specified properties. * @param [properties] Properties to set @@ -31004,9 +30998,6 @@ export namespace tabletmanagerdata { /** StopReplicationAndGetStatusResponse status */ status?: (replicationdata.IStopReplicationStatus|null); - - /** StopReplicationAndGetStatusResponse backup_running */ - backup_running?: (boolean|null); } /** Represents a StopReplicationAndGetStatusResponse. */ @@ -31021,9 +31012,6 @@ export namespace tabletmanagerdata { /** StopReplicationAndGetStatusResponse status. */ public status?: (replicationdata.IStopReplicationStatus|null); - /** StopReplicationAndGetStatusResponse backup_running. */ - public backup_running: boolean; - /** * Creates a new StopReplicationAndGetStatusResponse instance using the specified properties. * @param [properties] Properties to set @@ -31339,9 +31327,6 @@ export namespace tabletmanagerdata { /** BackupRequest backup_engine. */ public backup_engine?: (string|null); - /** BackupRequest _backup_engine. */ - public _backup_engine?: "backup_engine"; - /** * Creates a new BackupRequest instance using the specified properties. * @param [properties] Properties to set @@ -33960,9 +33945,6 @@ export namespace tabletmanagerdata { /** VDiffCoreOptions auto_start. */ public auto_start?: (boolean|null); - /** VDiffCoreOptions _auto_start. */ - public _auto_start?: "auto_start"; - /** * Creates a new VDiffCoreOptions instance using the specified properties. * @param [properties] Properties to set @@ -34150,6 +34132,109 @@ export namespace tabletmanagerdata { public static getTypeUrl(typeUrlPrefix?: string): string; } + /** Properties of a VDiffTableLastPK. */ + interface IVDiffTableLastPK { + + /** VDiffTableLastPK target */ + target?: (query.IQueryResult|null); + + /** VDiffTableLastPK source */ + source?: (query.IQueryResult|null); + } + + /** Represents a VDiffTableLastPK. */ + class VDiffTableLastPK implements IVDiffTableLastPK { + + /** + * Constructs a new VDiffTableLastPK. + * @param [properties] Properties to set + */ + constructor(properties?: tabletmanagerdata.IVDiffTableLastPK); + + /** VDiffTableLastPK target. */ + public target?: (query.IQueryResult|null); + + /** VDiffTableLastPK source. */ + public source?: (query.IQueryResult|null); + + /** + * Creates a new VDiffTableLastPK instance using the specified properties. + * @param [properties] Properties to set + * @returns VDiffTableLastPK instance + */ + public static create(properties?: tabletmanagerdata.IVDiffTableLastPK): tabletmanagerdata.VDiffTableLastPK; + + /** + * Encodes the specified VDiffTableLastPK message. Does not implicitly {@link tabletmanagerdata.VDiffTableLastPK.verify|verify} messages. + * @param message VDiffTableLastPK message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: tabletmanagerdata.IVDiffTableLastPK, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified VDiffTableLastPK message, length delimited. Does not implicitly {@link tabletmanagerdata.VDiffTableLastPK.verify|verify} messages. + * @param message VDiffTableLastPK message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: tabletmanagerdata.IVDiffTableLastPK, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a VDiffTableLastPK message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns VDiffTableLastPK + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): tabletmanagerdata.VDiffTableLastPK; + + /** + * Decodes a VDiffTableLastPK message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns VDiffTableLastPK + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): tabletmanagerdata.VDiffTableLastPK; + + /** + * Verifies a VDiffTableLastPK message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a VDiffTableLastPK message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns VDiffTableLastPK + */ + public static fromObject(object: { [k: string]: any }): tabletmanagerdata.VDiffTableLastPK; + + /** + * Creates a plain object from a VDiffTableLastPK message. Also converts values to other types if specified. + * @param message VDiffTableLastPK + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: tabletmanagerdata.VDiffTableLastPK, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this VDiffTableLastPK to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for VDiffTableLastPK + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + /** Properties of an UpdateVReplicationWorkflowRequest. */ interface IUpdateVReplicationWorkflowRequest { @@ -34171,8 +34256,14 @@ export namespace tabletmanagerdata { /** UpdateVReplicationWorkflowRequest state */ state?: (binlogdata.VReplicationWorkflowState|null); + /** UpdateVReplicationWorkflowRequest shards */ + shards?: (string[]|null); + /** UpdateVReplicationWorkflowRequest config_overrides */ config_overrides?: ({ [k: string]: string }|null); + + /** UpdateVReplicationWorkflowRequest message */ + message?: (string|null); } /** Represents an UpdateVReplicationWorkflowRequest. */ @@ -34202,17 +34293,14 @@ export namespace tabletmanagerdata { /** UpdateVReplicationWorkflowRequest state. */ public state?: (binlogdata.VReplicationWorkflowState|null); + /** UpdateVReplicationWorkflowRequest shards. */ + public shards: string[]; + /** UpdateVReplicationWorkflowRequest config_overrides. */ public config_overrides: { [k: string]: string }; - /** UpdateVReplicationWorkflowRequest _tablet_selection_preference. */ - public _tablet_selection_preference?: "tablet_selection_preference"; - - /** UpdateVReplicationWorkflowRequest _on_ddl. */ - public _on_ddl?: "on_ddl"; - - /** UpdateVReplicationWorkflowRequest _state. */ - public _state?: "state"; + /** UpdateVReplicationWorkflowRequest message. */ + public message?: (string|null); /** * Creates a new UpdateVReplicationWorkflowRequest instance using the specified properties. @@ -34438,15 +34526,6 @@ export namespace tabletmanagerdata { /** UpdateVReplicationWorkflowsRequest stop_position. */ public stop_position?: (string|null); - /** UpdateVReplicationWorkflowsRequest _state. */ - public _state?: "state"; - - /** UpdateVReplicationWorkflowsRequest _message. */ - public _message?: "message"; - - /** UpdateVReplicationWorkflowsRequest _stop_position. */ - public _stop_position?: "stop_position"; - /** * Creates a new UpdateVReplicationWorkflowsRequest instance using the specified properties. * @param [properties] Properties to set @@ -37382,6 +37461,9 @@ export namespace binlogdata { /** RowChange data_columns */ data_columns?: (binlogdata.RowChange.IBitmap|null); + + /** RowChange json_partial_values */ + json_partial_values?: (binlogdata.RowChange.IBitmap|null); } /** Represents a RowChange. */ @@ -37402,6 +37484,9 @@ export namespace binlogdata { /** RowChange data_columns. */ public data_columns?: (binlogdata.RowChange.IBitmap|null); + /** RowChange json_partial_values. */ + public json_partial_values?: (binlogdata.RowChange.IBitmap|null); + /** * Creates a new RowChange instance using the specified properties. * @param [properties] Properties to set @@ -40362,7 +40447,8 @@ export namespace query { HEXVAL = 4129, BITNUM = 4130, VECTOR = 2083, - RAW = 2084 + RAW = 2084, + ROW_TUPLE = 2085 } /** Properties of a Value. */ @@ -40721,6 +40807,9 @@ export namespace query { /** ExecuteOptions authoritative_timeout */ authoritative_timeout?: (number|Long|null); + + /** ExecuteOptions fetch_last_insert_id */ + fetch_last_insert_id?: (boolean|null); } /** Represents an ExecuteOptions. */ @@ -40771,6 +40860,9 @@ export namespace query { /** ExecuteOptions authoritative_timeout. */ public authoritative_timeout?: (number|Long|null); + /** ExecuteOptions fetch_last_insert_id. */ + public fetch_last_insert_id: boolean; + /** ExecuteOptions timeout. */ public timeout?: "authoritative_timeout"; @@ -41188,6 +41280,9 @@ export namespace query { /** QueryResult session_state_changes */ session_state_changes?: (string|null); + + /** QueryResult insert_id_changed */ + insert_id_changed?: (boolean|null); } /** Represents a QueryResult. */ @@ -41217,6 +41312,9 @@ export namespace query { /** QueryResult session_state_changes. */ public session_state_changes: string; + /** QueryResult insert_id_changed. */ + public insert_id_changed: boolean; + /** * Creates a new QueryResult instance using the specified properties. * @param [properties] Properties to set @@ -48195,9 +48293,6 @@ export namespace replicationdata { /** StopReplicationStatus after */ after?: (replicationdata.IStatus|null); - - /** StopReplicationStatus backup_running */ - backup_running?: (boolean|null); } /** Represents a StopReplicationStatus. */ @@ -48215,9 +48310,6 @@ export namespace replicationdata { /** StopReplicationStatus after. */ public after?: (replicationdata.IStatus|null); - /** StopReplicationStatus backup_running. */ - public backup_running: boolean; - /** * Creates a new StopReplicationStatus instance using the specified properties. * @param [properties] Properties to set @@ -48479,6 +48571,9 @@ export namespace replicationdata { /** FullStatus replication_configuration */ replication_configuration?: (replicationdata.IConfiguration|null); + + /** FullStatus disk_stalled */ + disk_stalled?: (boolean|null); } /** Represents a FullStatus. */ @@ -48556,6 +48651,9 @@ export namespace replicationdata { /** FullStatus replication_configuration. */ public replication_configuration?: (replicationdata.IConfiguration|null); + /** FullStatus disk_stalled. */ + public disk_stalled: boolean; + /** * Creates a new FullStatus instance using the specified properties. * @param [properties] Properties to set @@ -49600,9 +49698,6 @@ export namespace vschema { /** Column values. */ public values: string[]; - /** Column _nullable. */ - public _nullable?: "nullable"; - /** * Creates a new Column instance using the specified properties. * @param [properties] Properties to set @@ -54272,9 +54367,6 @@ export namespace vtctldata { /** BackupRequest backup_engine. */ public backup_engine?: (string|null); - /** BackupRequest _backup_engine. */ - public _backup_engine?: "backup_engine"; - /** * Creates a new BackupRequest instance using the specified properties. * @param [properties] Properties to set @@ -55849,6 +55941,236 @@ export namespace vtctldata { public static getTypeUrl(typeUrlPrefix?: string): string; } + /** Properties of a CopySchemaShardRequest. */ + interface ICopySchemaShardRequest { + + /** CopySchemaShardRequest source_tablet_alias */ + source_tablet_alias?: (topodata.ITabletAlias|null); + + /** CopySchemaShardRequest tables */ + tables?: (string[]|null); + + /** CopySchemaShardRequest exclude_tables */ + exclude_tables?: (string[]|null); + + /** CopySchemaShardRequest include_views */ + include_views?: (boolean|null); + + /** CopySchemaShardRequest skip_verify */ + skip_verify?: (boolean|null); + + /** CopySchemaShardRequest wait_replicas_timeout */ + wait_replicas_timeout?: (vttime.IDuration|null); + + /** CopySchemaShardRequest destination_keyspace */ + destination_keyspace?: (string|null); + + /** CopySchemaShardRequest destination_shard */ + destination_shard?: (string|null); + } + + /** Represents a CopySchemaShardRequest. */ + class CopySchemaShardRequest implements ICopySchemaShardRequest { + + /** + * Constructs a new CopySchemaShardRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.ICopySchemaShardRequest); + + /** CopySchemaShardRequest source_tablet_alias. */ + public source_tablet_alias?: (topodata.ITabletAlias|null); + + /** CopySchemaShardRequest tables. */ + public tables: string[]; + + /** CopySchemaShardRequest exclude_tables. */ + public exclude_tables: string[]; + + /** CopySchemaShardRequest include_views. */ + public include_views: boolean; + + /** CopySchemaShardRequest skip_verify. */ + public skip_verify: boolean; + + /** CopySchemaShardRequest wait_replicas_timeout. */ + public wait_replicas_timeout?: (vttime.IDuration|null); + + /** CopySchemaShardRequest destination_keyspace. */ + public destination_keyspace: string; + + /** CopySchemaShardRequest destination_shard. */ + public destination_shard: string; + + /** + * Creates a new CopySchemaShardRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns CopySchemaShardRequest instance + */ + public static create(properties?: vtctldata.ICopySchemaShardRequest): vtctldata.CopySchemaShardRequest; + + /** + * Encodes the specified CopySchemaShardRequest message. Does not implicitly {@link vtctldata.CopySchemaShardRequest.verify|verify} messages. + * @param message CopySchemaShardRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.ICopySchemaShardRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CopySchemaShardRequest message, length delimited. Does not implicitly {@link vtctldata.CopySchemaShardRequest.verify|verify} messages. + * @param message CopySchemaShardRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.ICopySchemaShardRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CopySchemaShardRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CopySchemaShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.CopySchemaShardRequest; + + /** + * Decodes a CopySchemaShardRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CopySchemaShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.CopySchemaShardRequest; + + /** + * Verifies a CopySchemaShardRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CopySchemaShardRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CopySchemaShardRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.CopySchemaShardRequest; + + /** + * Creates a plain object from a CopySchemaShardRequest message. Also converts values to other types if specified. + * @param message CopySchemaShardRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.CopySchemaShardRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CopySchemaShardRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for CopySchemaShardRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a CopySchemaShardResponse. */ + interface ICopySchemaShardResponse { + } + + /** Represents a CopySchemaShardResponse. */ + class CopySchemaShardResponse implements ICopySchemaShardResponse { + + /** + * Constructs a new CopySchemaShardResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.ICopySchemaShardResponse); + + /** + * Creates a new CopySchemaShardResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns CopySchemaShardResponse instance + */ + public static create(properties?: vtctldata.ICopySchemaShardResponse): vtctldata.CopySchemaShardResponse; + + /** + * Encodes the specified CopySchemaShardResponse message. Does not implicitly {@link vtctldata.CopySchemaShardResponse.verify|verify} messages. + * @param message CopySchemaShardResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.ICopySchemaShardResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CopySchemaShardResponse message, length delimited. Does not implicitly {@link vtctldata.CopySchemaShardResponse.verify|verify} messages. + * @param message CopySchemaShardResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.ICopySchemaShardResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CopySchemaShardResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CopySchemaShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.CopySchemaShardResponse; + + /** + * Decodes a CopySchemaShardResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CopySchemaShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.CopySchemaShardResponse; + + /** + * Verifies a CopySchemaShardResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CopySchemaShardResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CopySchemaShardResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.CopySchemaShardResponse; + + /** + * Creates a plain object from a CopySchemaShardResponse message. Also converts values to other types if specified. + * @param message CopySchemaShardResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.CopySchemaShardResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CopySchemaShardResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for CopySchemaShardResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + /** Properties of a CreateKeyspaceRequest. */ interface ICreateKeyspaceRequest { @@ -65789,6 +66111,206 @@ export namespace vtctldata { public static getTypeUrl(typeUrlPrefix?: string): string; } + /** Properties of a LookupVindexCompleteRequest. */ + interface ILookupVindexCompleteRequest { + + /** LookupVindexCompleteRequest keyspace */ + keyspace?: (string|null); + + /** LookupVindexCompleteRequest name */ + name?: (string|null); + + /** LookupVindexCompleteRequest table_keyspace */ + table_keyspace?: (string|null); + } + + /** Represents a LookupVindexCompleteRequest. */ + class LookupVindexCompleteRequest implements ILookupVindexCompleteRequest { + + /** + * Constructs a new LookupVindexCompleteRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.ILookupVindexCompleteRequest); + + /** LookupVindexCompleteRequest keyspace. */ + public keyspace: string; + + /** LookupVindexCompleteRequest name. */ + public name: string; + + /** LookupVindexCompleteRequest table_keyspace. */ + public table_keyspace: string; + + /** + * Creates a new LookupVindexCompleteRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns LookupVindexCompleteRequest instance + */ + public static create(properties?: vtctldata.ILookupVindexCompleteRequest): vtctldata.LookupVindexCompleteRequest; + + /** + * Encodes the specified LookupVindexCompleteRequest message. Does not implicitly {@link vtctldata.LookupVindexCompleteRequest.verify|verify} messages. + * @param message LookupVindexCompleteRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.ILookupVindexCompleteRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LookupVindexCompleteRequest message, length delimited. Does not implicitly {@link vtctldata.LookupVindexCompleteRequest.verify|verify} messages. + * @param message LookupVindexCompleteRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.ILookupVindexCompleteRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LookupVindexCompleteRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LookupVindexCompleteRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.LookupVindexCompleteRequest; + + /** + * Decodes a LookupVindexCompleteRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LookupVindexCompleteRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.LookupVindexCompleteRequest; + + /** + * Verifies a LookupVindexCompleteRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LookupVindexCompleteRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LookupVindexCompleteRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.LookupVindexCompleteRequest; + + /** + * Creates a plain object from a LookupVindexCompleteRequest message. Also converts values to other types if specified. + * @param message LookupVindexCompleteRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.LookupVindexCompleteRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LookupVindexCompleteRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for LookupVindexCompleteRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a LookupVindexCompleteResponse. */ + interface ILookupVindexCompleteResponse { + } + + /** Represents a LookupVindexCompleteResponse. */ + class LookupVindexCompleteResponse implements ILookupVindexCompleteResponse { + + /** + * Constructs a new LookupVindexCompleteResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.ILookupVindexCompleteResponse); + + /** + * Creates a new LookupVindexCompleteResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns LookupVindexCompleteResponse instance + */ + public static create(properties?: vtctldata.ILookupVindexCompleteResponse): vtctldata.LookupVindexCompleteResponse; + + /** + * Encodes the specified LookupVindexCompleteResponse message. Does not implicitly {@link vtctldata.LookupVindexCompleteResponse.verify|verify} messages. + * @param message LookupVindexCompleteResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.ILookupVindexCompleteResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LookupVindexCompleteResponse message, length delimited. Does not implicitly {@link vtctldata.LookupVindexCompleteResponse.verify|verify} messages. + * @param message LookupVindexCompleteResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.ILookupVindexCompleteResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LookupVindexCompleteResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LookupVindexCompleteResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.LookupVindexCompleteResponse; + + /** + * Decodes a LookupVindexCompleteResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LookupVindexCompleteResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.LookupVindexCompleteResponse; + + /** + * Verifies a LookupVindexCompleteResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LookupVindexCompleteResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LookupVindexCompleteResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.LookupVindexCompleteResponse; + + /** + * Creates a plain object from a LookupVindexCompleteResponse message. Also converts values to other types if specified. + * @param message LookupVindexCompleteResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.LookupVindexCompleteResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LookupVindexCompleteResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for LookupVindexCompleteResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + /** Properties of a LookupVindexCreateRequest. */ interface ILookupVindexCreateRequest { @@ -66024,6 +66546,9 @@ export namespace vtctldata { /** LookupVindexExternalizeRequest table_keyspace */ table_keyspace?: (string|null); + + /** LookupVindexExternalizeRequest delete_workflow */ + delete_workflow?: (boolean|null); } /** Represents a LookupVindexExternalizeRequest. */ @@ -66044,6 +66569,9 @@ export namespace vtctldata { /** LookupVindexExternalizeRequest table_keyspace. */ public table_keyspace: string; + /** LookupVindexExternalizeRequest delete_workflow. */ + public delete_workflow: boolean; + /** * Creates a new LookupVindexExternalizeRequest instance using the specified properties. * @param [properties] Properties to set @@ -66125,6 +66653,9 @@ export namespace vtctldata { /** Properties of a LookupVindexExternalizeResponse. */ interface ILookupVindexExternalizeResponse { + /** LookupVindexExternalizeResponse workflow_stopped */ + workflow_stopped?: (boolean|null); + /** LookupVindexExternalizeResponse workflow_deleted */ workflow_deleted?: (boolean|null); } @@ -66138,6 +66669,9 @@ export namespace vtctldata { */ constructor(properties?: vtctldata.ILookupVindexExternalizeResponse); + /** LookupVindexExternalizeResponse workflow_stopped. */ + public workflow_stopped: boolean; + /** LookupVindexExternalizeResponse workflow_deleted. */ public workflow_deleted: boolean; @@ -66219,6 +66753,206 @@ export namespace vtctldata { public static getTypeUrl(typeUrlPrefix?: string): string; } + /** Properties of a LookupVindexInternalizeRequest. */ + interface ILookupVindexInternalizeRequest { + + /** LookupVindexInternalizeRequest keyspace */ + keyspace?: (string|null); + + /** LookupVindexInternalizeRequest name */ + name?: (string|null); + + /** LookupVindexInternalizeRequest table_keyspace */ + table_keyspace?: (string|null); + } + + /** Represents a LookupVindexInternalizeRequest. */ + class LookupVindexInternalizeRequest implements ILookupVindexInternalizeRequest { + + /** + * Constructs a new LookupVindexInternalizeRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.ILookupVindexInternalizeRequest); + + /** LookupVindexInternalizeRequest keyspace. */ + public keyspace: string; + + /** LookupVindexInternalizeRequest name. */ + public name: string; + + /** LookupVindexInternalizeRequest table_keyspace. */ + public table_keyspace: string; + + /** + * Creates a new LookupVindexInternalizeRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns LookupVindexInternalizeRequest instance + */ + public static create(properties?: vtctldata.ILookupVindexInternalizeRequest): vtctldata.LookupVindexInternalizeRequest; + + /** + * Encodes the specified LookupVindexInternalizeRequest message. Does not implicitly {@link vtctldata.LookupVindexInternalizeRequest.verify|verify} messages. + * @param message LookupVindexInternalizeRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.ILookupVindexInternalizeRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LookupVindexInternalizeRequest message, length delimited. Does not implicitly {@link vtctldata.LookupVindexInternalizeRequest.verify|verify} messages. + * @param message LookupVindexInternalizeRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.ILookupVindexInternalizeRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LookupVindexInternalizeRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LookupVindexInternalizeRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.LookupVindexInternalizeRequest; + + /** + * Decodes a LookupVindexInternalizeRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LookupVindexInternalizeRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.LookupVindexInternalizeRequest; + + /** + * Verifies a LookupVindexInternalizeRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LookupVindexInternalizeRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LookupVindexInternalizeRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.LookupVindexInternalizeRequest; + + /** + * Creates a plain object from a LookupVindexInternalizeRequest message. Also converts values to other types if specified. + * @param message LookupVindexInternalizeRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.LookupVindexInternalizeRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LookupVindexInternalizeRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for LookupVindexInternalizeRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a LookupVindexInternalizeResponse. */ + interface ILookupVindexInternalizeResponse { + } + + /** Represents a LookupVindexInternalizeResponse. */ + class LookupVindexInternalizeResponse implements ILookupVindexInternalizeResponse { + + /** + * Constructs a new LookupVindexInternalizeResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.ILookupVindexInternalizeResponse); + + /** + * Creates a new LookupVindexInternalizeResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns LookupVindexInternalizeResponse instance + */ + public static create(properties?: vtctldata.ILookupVindexInternalizeResponse): vtctldata.LookupVindexInternalizeResponse; + + /** + * Encodes the specified LookupVindexInternalizeResponse message. Does not implicitly {@link vtctldata.LookupVindexInternalizeResponse.verify|verify} messages. + * @param message LookupVindexInternalizeResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.ILookupVindexInternalizeResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LookupVindexInternalizeResponse message, length delimited. Does not implicitly {@link vtctldata.LookupVindexInternalizeResponse.verify|verify} messages. + * @param message LookupVindexInternalizeResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.ILookupVindexInternalizeResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LookupVindexInternalizeResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LookupVindexInternalizeResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.LookupVindexInternalizeResponse; + + /** + * Decodes a LookupVindexInternalizeResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LookupVindexInternalizeResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.LookupVindexInternalizeResponse; + + /** + * Verifies a LookupVindexInternalizeResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LookupVindexInternalizeResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LookupVindexInternalizeResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.LookupVindexInternalizeResponse; + + /** + * Creates a plain object from a LookupVindexInternalizeResponse message. Also converts values to other types if specified. + * @param message LookupVindexInternalizeResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.LookupVindexInternalizeResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LookupVindexInternalizeResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for LookupVindexInternalizeResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + /** Properties of a MaterializeCreateRequest. */ interface IMaterializeCreateRequest { @@ -75629,6 +76363,200 @@ export namespace vtctldata { public static getTypeUrl(typeUrlPrefix?: string): string; } + /** Properties of a ValidatePermissionsKeyspaceRequest. */ + interface IValidatePermissionsKeyspaceRequest { + + /** ValidatePermissionsKeyspaceRequest keyspace */ + keyspace?: (string|null); + + /** ValidatePermissionsKeyspaceRequest shards */ + shards?: (string[]|null); + } + + /** Represents a ValidatePermissionsKeyspaceRequest. */ + class ValidatePermissionsKeyspaceRequest implements IValidatePermissionsKeyspaceRequest { + + /** + * Constructs a new ValidatePermissionsKeyspaceRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IValidatePermissionsKeyspaceRequest); + + /** ValidatePermissionsKeyspaceRequest keyspace. */ + public keyspace: string; + + /** ValidatePermissionsKeyspaceRequest shards. */ + public shards: string[]; + + /** + * Creates a new ValidatePermissionsKeyspaceRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns ValidatePermissionsKeyspaceRequest instance + */ + public static create(properties?: vtctldata.IValidatePermissionsKeyspaceRequest): vtctldata.ValidatePermissionsKeyspaceRequest; + + /** + * Encodes the specified ValidatePermissionsKeyspaceRequest message. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceRequest.verify|verify} messages. + * @param message ValidatePermissionsKeyspaceRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IValidatePermissionsKeyspaceRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ValidatePermissionsKeyspaceRequest message, length delimited. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceRequest.verify|verify} messages. + * @param message ValidatePermissionsKeyspaceRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IValidatePermissionsKeyspaceRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ValidatePermissionsKeyspaceRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ValidatePermissionsKeyspaceRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ValidatePermissionsKeyspaceRequest; + + /** + * Decodes a ValidatePermissionsKeyspaceRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ValidatePermissionsKeyspaceRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ValidatePermissionsKeyspaceRequest; + + /** + * Verifies a ValidatePermissionsKeyspaceRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ValidatePermissionsKeyspaceRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ValidatePermissionsKeyspaceRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ValidatePermissionsKeyspaceRequest; + + /** + * Creates a plain object from a ValidatePermissionsKeyspaceRequest message. Also converts values to other types if specified. + * @param message ValidatePermissionsKeyspaceRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ValidatePermissionsKeyspaceRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ValidatePermissionsKeyspaceRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for ValidatePermissionsKeyspaceRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a ValidatePermissionsKeyspaceResponse. */ + interface IValidatePermissionsKeyspaceResponse { + } + + /** Represents a ValidatePermissionsKeyspaceResponse. */ + class ValidatePermissionsKeyspaceResponse implements IValidatePermissionsKeyspaceResponse { + + /** + * Constructs a new ValidatePermissionsKeyspaceResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IValidatePermissionsKeyspaceResponse); + + /** + * Creates a new ValidatePermissionsKeyspaceResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns ValidatePermissionsKeyspaceResponse instance + */ + public static create(properties?: vtctldata.IValidatePermissionsKeyspaceResponse): vtctldata.ValidatePermissionsKeyspaceResponse; + + /** + * Encodes the specified ValidatePermissionsKeyspaceResponse message. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceResponse.verify|verify} messages. + * @param message ValidatePermissionsKeyspaceResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IValidatePermissionsKeyspaceResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ValidatePermissionsKeyspaceResponse message, length delimited. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceResponse.verify|verify} messages. + * @param message ValidatePermissionsKeyspaceResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IValidatePermissionsKeyspaceResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ValidatePermissionsKeyspaceResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ValidatePermissionsKeyspaceResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ValidatePermissionsKeyspaceResponse; + + /** + * Decodes a ValidatePermissionsKeyspaceResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ValidatePermissionsKeyspaceResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ValidatePermissionsKeyspaceResponse; + + /** + * Verifies a ValidatePermissionsKeyspaceResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ValidatePermissionsKeyspaceResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ValidatePermissionsKeyspaceResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ValidatePermissionsKeyspaceResponse; + + /** + * Creates a plain object from a ValidatePermissionsKeyspaceResponse message. Also converts values to other types if specified. + * @param message ValidatePermissionsKeyspaceResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ValidatePermissionsKeyspaceResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ValidatePermissionsKeyspaceResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for ValidatePermissionsKeyspaceResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + /** Properties of a ValidateSchemaKeyspaceRequest. */ interface IValidateSchemaKeyspaceRequest { @@ -75646,6 +76574,9 @@ export namespace vtctldata { /** ValidateSchemaKeyspaceRequest include_vschema */ include_vschema?: (boolean|null); + + /** ValidateSchemaKeyspaceRequest shards */ + shards?: (string[]|null); } /** Represents a ValidateSchemaKeyspaceRequest. */ @@ -75672,6 +76603,9 @@ export namespace vtctldata { /** ValidateSchemaKeyspaceRequest include_vschema. */ public include_vschema: boolean; + /** ValidateSchemaKeyspaceRequest shards. */ + public shards: string[]; + /** * Creates a new ValidateSchemaKeyspaceRequest instance using the specified properties. * @param [properties] Properties to set @@ -76822,9 +77756,6 @@ export namespace vtctldata { /** VDiffCreateRequest auto_start. */ public auto_start?: (boolean|null); - /** VDiffCreateRequest _auto_start. */ - public _auto_start?: "auto_start"; - /** * Creates a new VDiffCreateRequest instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 6d7ca92806b..c33f540935b 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -61392,7 +61392,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { * @memberof tabletmanagerdata * @interface IReplicationStatusResponse * @property {replicationdata.IStatus|null} [status] ReplicationStatusResponse status - * @property {boolean|null} [backup_running] ReplicationStatusResponse backup_running */ /** @@ -61418,14 +61417,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { */ ReplicationStatusResponse.prototype.status = null; - /** - * ReplicationStatusResponse backup_running. - * @member {boolean} backup_running - * @memberof tabletmanagerdata.ReplicationStatusResponse - * @instance - */ - ReplicationStatusResponse.prototype.backup_running = false; - /** * Creates a new ReplicationStatusResponse instance using the specified properties. * @function create @@ -61452,8 +61443,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { writer = $Writer.create(); if (message.status != null && Object.hasOwnProperty.call(message, "status")) $root.replicationdata.Status.encode(message.status, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.backup_running != null && Object.hasOwnProperty.call(message, "backup_running")) - writer.uint32(/* id 2, wireType 0 =*/16).bool(message.backup_running); return writer; }; @@ -61492,10 +61481,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { message.status = $root.replicationdata.Status.decode(reader, reader.uint32()); break; } - case 2: { - message.backup_running = reader.bool(); - break; - } default: reader.skipType(tag & 7); break; @@ -61536,9 +61521,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (error) return "status." + error; } - if (message.backup_running != null && message.hasOwnProperty("backup_running")) - if (typeof message.backup_running !== "boolean") - return "backup_running: boolean expected"; return null; }; @@ -61559,8 +61541,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { throw TypeError(".tabletmanagerdata.ReplicationStatusResponse.status: object expected"); message.status = $root.replicationdata.Status.fromObject(object.status); } - if (object.backup_running != null) - message.backup_running = Boolean(object.backup_running); return message; }; @@ -61577,14 +61557,10 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (!options) options = {}; let object = {}; - if (options.defaults) { + if (options.defaults) object.status = null; - object.backup_running = false; - } if (message.status != null && message.hasOwnProperty("status")) object.status = $root.replicationdata.Status.toObject(message.status, options); - if (message.backup_running != null && message.hasOwnProperty("backup_running")) - object.backup_running = message.backup_running; return object; }; @@ -70588,7 +70564,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { * @memberof tabletmanagerdata * @interface IStopReplicationAndGetStatusResponse * @property {replicationdata.IStopReplicationStatus|null} [status] StopReplicationAndGetStatusResponse status - * @property {boolean|null} [backup_running] StopReplicationAndGetStatusResponse backup_running */ /** @@ -70614,14 +70589,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { */ StopReplicationAndGetStatusResponse.prototype.status = null; - /** - * StopReplicationAndGetStatusResponse backup_running. - * @member {boolean} backup_running - * @memberof tabletmanagerdata.StopReplicationAndGetStatusResponse - * @instance - */ - StopReplicationAndGetStatusResponse.prototype.backup_running = false; - /** * Creates a new StopReplicationAndGetStatusResponse instance using the specified properties. * @function create @@ -70648,8 +70615,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { writer = $Writer.create(); if (message.status != null && Object.hasOwnProperty.call(message, "status")) $root.replicationdata.StopReplicationStatus.encode(message.status, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.backup_running != null && Object.hasOwnProperty.call(message, "backup_running")) - writer.uint32(/* id 3, wireType 0 =*/24).bool(message.backup_running); return writer; }; @@ -70688,10 +70653,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { message.status = $root.replicationdata.StopReplicationStatus.decode(reader, reader.uint32()); break; } - case 3: { - message.backup_running = reader.bool(); - break; - } default: reader.skipType(tag & 7); break; @@ -70732,9 +70693,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (error) return "status." + error; } - if (message.backup_running != null && message.hasOwnProperty("backup_running")) - if (typeof message.backup_running !== "boolean") - return "backup_running: boolean expected"; return null; }; @@ -70755,8 +70713,6 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { throw TypeError(".tabletmanagerdata.StopReplicationAndGetStatusResponse.status: object expected"); message.status = $root.replicationdata.StopReplicationStatus.fromObject(object.status); } - if (object.backup_running != null) - message.backup_running = Boolean(object.backup_running); return message; }; @@ -70773,14 +70729,10 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (!options) options = {}; let object = {}; - if (options.defaults) { + if (options.defaults) object.status = null; - object.backup_running = false; - } if (message.status != null && message.hasOwnProperty("status")) object.status = $root.replicationdata.StopReplicationStatus.toObject(message.status, options); - if (message.backup_running != null && message.hasOwnProperty("backup_running")) - object.backup_running = message.backup_running; return object; }; @@ -71290,12 +71242,7 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { // OneOf field names bound to virtual getters and setters let $oneOfFields; - /** - * BackupRequest _backup_engine. - * @member {"backup_engine"|undefined} _backup_engine - * @memberof tabletmanagerdata.BackupRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(BackupRequest.prototype, "_backup_engine", { get: $util.oneOfGetter($oneOfFields = ["backup_engine"]), set: $util.oneOfSetter($oneOfFields) @@ -78298,12 +78245,7 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { // OneOf field names bound to virtual getters and setters let $oneOfFields; - /** - * VDiffCoreOptions _auto_start. - * @member {"auto_start"|undefined} _auto_start - * @memberof tabletmanagerdata.VDiffCoreOptions - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(VDiffCoreOptions.prototype, "_auto_start", { get: $util.oneOfGetter($oneOfFields = ["auto_start"]), set: $util.oneOfSetter($oneOfFields) @@ -78947,6 +78889,257 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { return VDiffOptions; })(); + tabletmanagerdata.VDiffTableLastPK = (function() { + + /** + * Properties of a VDiffTableLastPK. + * @memberof tabletmanagerdata + * @interface IVDiffTableLastPK + * @property {query.IQueryResult|null} [target] VDiffTableLastPK target + * @property {query.IQueryResult|null} [source] VDiffTableLastPK source + */ + + /** + * Constructs a new VDiffTableLastPK. + * @memberof tabletmanagerdata + * @classdesc Represents a VDiffTableLastPK. + * @implements IVDiffTableLastPK + * @constructor + * @param {tabletmanagerdata.IVDiffTableLastPK=} [properties] Properties to set + */ + function VDiffTableLastPK(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * VDiffTableLastPK target. + * @member {query.IQueryResult|null|undefined} target + * @memberof tabletmanagerdata.VDiffTableLastPK + * @instance + */ + VDiffTableLastPK.prototype.target = null; + + /** + * VDiffTableLastPK source. + * @member {query.IQueryResult|null|undefined} source + * @memberof tabletmanagerdata.VDiffTableLastPK + * @instance + */ + VDiffTableLastPK.prototype.source = null; + + // OneOf field names bound to virtual getters and setters + let $oneOfFields; + + // Virtual OneOf for proto3 optional field + Object.defineProperty(VDiffTableLastPK.prototype, "_source", { + get: $util.oneOfGetter($oneOfFields = ["source"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new VDiffTableLastPK instance using the specified properties. + * @function create + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {tabletmanagerdata.IVDiffTableLastPK=} [properties] Properties to set + * @returns {tabletmanagerdata.VDiffTableLastPK} VDiffTableLastPK instance + */ + VDiffTableLastPK.create = function create(properties) { + return new VDiffTableLastPK(properties); + }; + + /** + * Encodes the specified VDiffTableLastPK message. Does not implicitly {@link tabletmanagerdata.VDiffTableLastPK.verify|verify} messages. + * @function encode + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {tabletmanagerdata.IVDiffTableLastPK} message VDiffTableLastPK message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + VDiffTableLastPK.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.target != null && Object.hasOwnProperty.call(message, "target")) + $root.query.QueryResult.encode(message.target, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.source != null && Object.hasOwnProperty.call(message, "source")) + $root.query.QueryResult.encode(message.source, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified VDiffTableLastPK message, length delimited. Does not implicitly {@link tabletmanagerdata.VDiffTableLastPK.verify|verify} messages. + * @function encodeDelimited + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {tabletmanagerdata.IVDiffTableLastPK} message VDiffTableLastPK message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + VDiffTableLastPK.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a VDiffTableLastPK message from the specified reader or buffer. + * @function decode + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {tabletmanagerdata.VDiffTableLastPK} VDiffTableLastPK + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + VDiffTableLastPK.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.tabletmanagerdata.VDiffTableLastPK(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.target = $root.query.QueryResult.decode(reader, reader.uint32()); + break; + } + case 2: { + message.source = $root.query.QueryResult.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a VDiffTableLastPK message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {tabletmanagerdata.VDiffTableLastPK} VDiffTableLastPK + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + VDiffTableLastPK.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a VDiffTableLastPK message. + * @function verify + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + VDiffTableLastPK.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + let properties = {}; + if (message.target != null && message.hasOwnProperty("target")) { + let error = $root.query.QueryResult.verify(message.target); + if (error) + return "target." + error; + } + if (message.source != null && message.hasOwnProperty("source")) { + properties._source = 1; + { + let error = $root.query.QueryResult.verify(message.source); + if (error) + return "source." + error; + } + } + return null; + }; + + /** + * Creates a VDiffTableLastPK message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {Object.} object Plain object + * @returns {tabletmanagerdata.VDiffTableLastPK} VDiffTableLastPK + */ + VDiffTableLastPK.fromObject = function fromObject(object) { + if (object instanceof $root.tabletmanagerdata.VDiffTableLastPK) + return object; + let message = new $root.tabletmanagerdata.VDiffTableLastPK(); + if (object.target != null) { + if (typeof object.target !== "object") + throw TypeError(".tabletmanagerdata.VDiffTableLastPK.target: object expected"); + message.target = $root.query.QueryResult.fromObject(object.target); + } + if (object.source != null) { + if (typeof object.source !== "object") + throw TypeError(".tabletmanagerdata.VDiffTableLastPK.source: object expected"); + message.source = $root.query.QueryResult.fromObject(object.source); + } + return message; + }; + + /** + * Creates a plain object from a VDiffTableLastPK message. Also converts values to other types if specified. + * @function toObject + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {tabletmanagerdata.VDiffTableLastPK} message VDiffTableLastPK + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + VDiffTableLastPK.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) + object.target = null; + if (message.target != null && message.hasOwnProperty("target")) + object.target = $root.query.QueryResult.toObject(message.target, options); + if (message.source != null && message.hasOwnProperty("source")) { + object.source = $root.query.QueryResult.toObject(message.source, options); + if (options.oneofs) + object._source = "source"; + } + return object; + }; + + /** + * Converts this VDiffTableLastPK to JSON. + * @function toJSON + * @memberof tabletmanagerdata.VDiffTableLastPK + * @instance + * @returns {Object.} JSON object + */ + VDiffTableLastPK.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for VDiffTableLastPK + * @function getTypeUrl + * @memberof tabletmanagerdata.VDiffTableLastPK + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + VDiffTableLastPK.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/tabletmanagerdata.VDiffTableLastPK"; + }; + + return VDiffTableLastPK; + })(); + tabletmanagerdata.UpdateVReplicationWorkflowRequest = (function() { /** @@ -78959,7 +79152,9 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { * @property {tabletmanagerdata.TabletSelectionPreference|null} [tablet_selection_preference] UpdateVReplicationWorkflowRequest tablet_selection_preference * @property {binlogdata.OnDDLAction|null} [on_ddl] UpdateVReplicationWorkflowRequest on_ddl * @property {binlogdata.VReplicationWorkflowState|null} [state] UpdateVReplicationWorkflowRequest state + * @property {Array.|null} [shards] UpdateVReplicationWorkflowRequest shards * @property {Object.|null} [config_overrides] UpdateVReplicationWorkflowRequest config_overrides + * @property {string|null} [message] UpdateVReplicationWorkflowRequest message */ /** @@ -78973,6 +79168,7 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { function UpdateVReplicationWorkflowRequest(properties) { this.cells = []; this.tablet_types = []; + this.shards = []; this.config_overrides = {}; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) @@ -79028,6 +79224,14 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { */ UpdateVReplicationWorkflowRequest.prototype.state = null; + /** + * UpdateVReplicationWorkflowRequest shards. + * @member {Array.} shards + * @memberof tabletmanagerdata.UpdateVReplicationWorkflowRequest + * @instance + */ + UpdateVReplicationWorkflowRequest.prototype.shards = $util.emptyArray; + /** * UpdateVReplicationWorkflowRequest config_overrides. * @member {Object.} config_overrides @@ -79036,42 +79240,41 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { */ UpdateVReplicationWorkflowRequest.prototype.config_overrides = $util.emptyObject; - // OneOf field names bound to virtual getters and setters - let $oneOfFields; - /** - * UpdateVReplicationWorkflowRequest _tablet_selection_preference. - * @member {"tablet_selection_preference"|undefined} _tablet_selection_preference + * UpdateVReplicationWorkflowRequest message. + * @member {string|null|undefined} message * @memberof tabletmanagerdata.UpdateVReplicationWorkflowRequest * @instance */ + UpdateVReplicationWorkflowRequest.prototype.message = null; + + // OneOf field names bound to virtual getters and setters + let $oneOfFields; + + // Virtual OneOf for proto3 optional field Object.defineProperty(UpdateVReplicationWorkflowRequest.prototype, "_tablet_selection_preference", { get: $util.oneOfGetter($oneOfFields = ["tablet_selection_preference"]), set: $util.oneOfSetter($oneOfFields) }); - /** - * UpdateVReplicationWorkflowRequest _on_ddl. - * @member {"on_ddl"|undefined} _on_ddl - * @memberof tabletmanagerdata.UpdateVReplicationWorkflowRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(UpdateVReplicationWorkflowRequest.prototype, "_on_ddl", { get: $util.oneOfGetter($oneOfFields = ["on_ddl"]), set: $util.oneOfSetter($oneOfFields) }); - /** - * UpdateVReplicationWorkflowRequest _state. - * @member {"state"|undefined} _state - * @memberof tabletmanagerdata.UpdateVReplicationWorkflowRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(UpdateVReplicationWorkflowRequest.prototype, "_state", { get: $util.oneOfGetter($oneOfFields = ["state"]), set: $util.oneOfSetter($oneOfFields) }); + // Virtual OneOf for proto3 optional field + Object.defineProperty(UpdateVReplicationWorkflowRequest.prototype, "_message", { + get: $util.oneOfGetter($oneOfFields = ["message"]), + set: $util.oneOfSetter($oneOfFields) + }); + /** * Creates a new UpdateVReplicationWorkflowRequest instance using the specified properties. * @function create @@ -79113,9 +79316,14 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { writer.uint32(/* id 5, wireType 0 =*/40).int32(message.on_ddl); if (message.state != null && Object.hasOwnProperty.call(message, "state")) writer.uint32(/* id 6, wireType 0 =*/48).int32(message.state); + if (message.shards != null && message.shards.length) + for (let i = 0; i < message.shards.length; ++i) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.shards[i]); if (message.config_overrides != null && Object.hasOwnProperty.call(message, "config_overrides")) for (let keys = Object.keys(message.config_overrides), i = 0; i < keys.length; ++i) writer.uint32(/* id 8, wireType 2 =*/66).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.config_overrides[keys[i]]).ldelim(); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.message); return writer; }; @@ -79183,6 +79391,12 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { message.state = reader.int32(); break; } + case 7: { + if (!(message.shards && message.shards.length)) + message.shards = []; + message.shards.push(reader.string()); + break; + } case 8: { if (message.config_overrides === $util.emptyObject) message.config_overrides = {}; @@ -79206,6 +79420,10 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { message.config_overrides[key] = value; break; } + case 9: { + message.message = reader.string(); + break; + } default: reader.skipType(tag & 7); break; @@ -79311,6 +79529,13 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { break; } } + if (message.shards != null && message.hasOwnProperty("shards")) { + if (!Array.isArray(message.shards)) + return "shards: array expected"; + for (let i = 0; i < message.shards.length; ++i) + if (!$util.isString(message.shards[i])) + return "shards: string[] expected"; + } if (message.config_overrides != null && message.hasOwnProperty("config_overrides")) { if (!$util.isObject(message.config_overrides)) return "config_overrides: object expected"; @@ -79319,6 +79544,11 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (!$util.isString(message.config_overrides[key[i]])) return "config_overrides: string{k:string} expected"; } + if (message.message != null && message.hasOwnProperty("message")) { + properties._message = 1; + if (!$util.isString(message.message)) + return "message: string expected"; + } return null; }; @@ -79480,6 +79710,13 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { message.state = 6; break; } + if (object.shards) { + if (!Array.isArray(object.shards)) + throw TypeError(".tabletmanagerdata.UpdateVReplicationWorkflowRequest.shards: array expected"); + message.shards = []; + for (let i = 0; i < object.shards.length; ++i) + message.shards[i] = String(object.shards[i]); + } if (object.config_overrides) { if (typeof object.config_overrides !== "object") throw TypeError(".tabletmanagerdata.UpdateVReplicationWorkflowRequest.config_overrides: object expected"); @@ -79487,6 +79724,8 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { for (let keys = Object.keys(object.config_overrides), i = 0; i < keys.length; ++i) message.config_overrides[keys[i]] = String(object.config_overrides[keys[i]]); } + if (object.message != null) + message.message = String(object.message); return message; }; @@ -79506,6 +79745,7 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (options.arrays || options.defaults) { object.cells = []; object.tablet_types = []; + object.shards = []; } if (options.objects || options.defaults) object.config_overrides = {}; @@ -79538,12 +79778,22 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (options.oneofs) object._state = "state"; } + if (message.shards && message.shards.length) { + object.shards = []; + for (let j = 0; j < message.shards.length; ++j) + object.shards[j] = message.shards[j]; + } let keys2; if (message.config_overrides && (keys2 = Object.keys(message.config_overrides)).length) { object.config_overrides = {}; for (let j = 0; j < keys2.length; ++j) object.config_overrides[keys2[j]] = message.config_overrides[keys2[j]]; } + if (message.message != null && message.hasOwnProperty("message")) { + object.message = message.message; + if (options.oneofs) + object._message = "message"; + } return object; }; @@ -79866,34 +80116,19 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { // OneOf field names bound to virtual getters and setters let $oneOfFields; - /** - * UpdateVReplicationWorkflowsRequest _state. - * @member {"state"|undefined} _state - * @memberof tabletmanagerdata.UpdateVReplicationWorkflowsRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(UpdateVReplicationWorkflowsRequest.prototype, "_state", { get: $util.oneOfGetter($oneOfFields = ["state"]), set: $util.oneOfSetter($oneOfFields) }); - /** - * UpdateVReplicationWorkflowsRequest _message. - * @member {"message"|undefined} _message - * @memberof tabletmanagerdata.UpdateVReplicationWorkflowsRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(UpdateVReplicationWorkflowsRequest.prototype, "_message", { get: $util.oneOfGetter($oneOfFields = ["message"]), set: $util.oneOfSetter($oneOfFields) }); - /** - * UpdateVReplicationWorkflowsRequest _stop_position. - * @member {"stop_position"|undefined} _stop_position - * @memberof tabletmanagerdata.UpdateVReplicationWorkflowsRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(UpdateVReplicationWorkflowsRequest.prototype, "_stop_position", { get: $util.oneOfGetter($oneOfFields = ["stop_position"]), set: $util.oneOfSetter($oneOfFields) @@ -87829,6 +88064,7 @@ export const binlogdata = $root.binlogdata = (() => { * @property {query.IRow|null} [before] RowChange before * @property {query.IRow|null} [after] RowChange after * @property {binlogdata.RowChange.IBitmap|null} [data_columns] RowChange data_columns + * @property {binlogdata.RowChange.IBitmap|null} [json_partial_values] RowChange json_partial_values */ /** @@ -87870,6 +88106,14 @@ export const binlogdata = $root.binlogdata = (() => { */ RowChange.prototype.data_columns = null; + /** + * RowChange json_partial_values. + * @member {binlogdata.RowChange.IBitmap|null|undefined} json_partial_values + * @memberof binlogdata.RowChange + * @instance + */ + RowChange.prototype.json_partial_values = null; + /** * Creates a new RowChange instance using the specified properties. * @function create @@ -87900,6 +88144,8 @@ export const binlogdata = $root.binlogdata = (() => { $root.query.Row.encode(message.after, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); if (message.data_columns != null && Object.hasOwnProperty.call(message, "data_columns")) $root.binlogdata.RowChange.Bitmap.encode(message.data_columns, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.json_partial_values != null && Object.hasOwnProperty.call(message, "json_partial_values")) + $root.binlogdata.RowChange.Bitmap.encode(message.json_partial_values, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); return writer; }; @@ -87946,6 +88192,10 @@ export const binlogdata = $root.binlogdata = (() => { message.data_columns = $root.binlogdata.RowChange.Bitmap.decode(reader, reader.uint32()); break; } + case 4: { + message.json_partial_values = $root.binlogdata.RowChange.Bitmap.decode(reader, reader.uint32()); + break; + } default: reader.skipType(tag & 7); break; @@ -87996,6 +88246,11 @@ export const binlogdata = $root.binlogdata = (() => { if (error) return "data_columns." + error; } + if (message.json_partial_values != null && message.hasOwnProperty("json_partial_values")) { + let error = $root.binlogdata.RowChange.Bitmap.verify(message.json_partial_values); + if (error) + return "json_partial_values." + error; + } return null; }; @@ -88026,6 +88281,11 @@ export const binlogdata = $root.binlogdata = (() => { throw TypeError(".binlogdata.RowChange.data_columns: object expected"); message.data_columns = $root.binlogdata.RowChange.Bitmap.fromObject(object.data_columns); } + if (object.json_partial_values != null) { + if (typeof object.json_partial_values !== "object") + throw TypeError(".binlogdata.RowChange.json_partial_values: object expected"); + message.json_partial_values = $root.binlogdata.RowChange.Bitmap.fromObject(object.json_partial_values); + } return message; }; @@ -88046,6 +88306,7 @@ export const binlogdata = $root.binlogdata = (() => { object.before = null; object.after = null; object.data_columns = null; + object.json_partial_values = null; } if (message.before != null && message.hasOwnProperty("before")) object.before = $root.query.Row.toObject(message.before, options); @@ -88053,6 +88314,8 @@ export const binlogdata = $root.binlogdata = (() => { object.after = $root.query.Row.toObject(message.after, options); if (message.data_columns != null && message.hasOwnProperty("data_columns")) object.data_columns = $root.binlogdata.RowChange.Bitmap.toObject(message.data_columns, options); + if (message.json_partial_values != null && message.hasOwnProperty("json_partial_values")) + object.json_partial_values = $root.binlogdata.RowChange.Bitmap.toObject(message.json_partial_values, options); return object; }; @@ -95843,6 +96106,7 @@ export const query = $root.query = (() => { * @property {number} BITNUM=4130 BITNUM value * @property {number} VECTOR=2083 VECTOR value * @property {number} RAW=2084 RAW value + * @property {number} ROW_TUPLE=2085 ROW_TUPLE value */ query.Type = (function() { const valuesById = {}, values = Object.create(valuesById); @@ -95883,6 +96147,7 @@ export const query = $root.query = (() => { values[valuesById[4130] = "BITNUM"] = 4130; values[valuesById[2083] = "VECTOR"] = 2083; values[valuesById[2084] = "RAW"] = 2084; + values[valuesById[2085] = "ROW_TUPLE"] = 2085; return values; })(); @@ -96073,6 +96338,7 @@ export const query = $root.query = (() => { case 4130: case 2083: case 2084: + case 2085: break; } if (message.value != null && message.hasOwnProperty("value")) @@ -96248,6 +96514,10 @@ export const query = $root.query = (() => { case 2084: message.type = 2084; break; + case "ROW_TUPLE": + case 2085: + message.type = 2085; + break; } if (object.value != null) if (typeof object.value === "string") @@ -96522,6 +96792,7 @@ export const query = $root.query = (() => { case 4130: case 2083: case 2084: + case 2085: break; } if (message.value != null && message.hasOwnProperty("value")) @@ -96706,6 +96977,10 @@ export const query = $root.query = (() => { case 2084: message.type = 2084; break; + case "ROW_TUPLE": + case 2085: + message.type = 2085; + break; } if (object.value != null) if (typeof object.value === "string") @@ -97079,6 +97354,7 @@ export const query = $root.query = (() => { * @property {string|null} [WorkloadName] ExecuteOptions WorkloadName * @property {string|null} [priority] ExecuteOptions priority * @property {number|Long|null} [authoritative_timeout] ExecuteOptions authoritative_timeout + * @property {boolean|null} [fetch_last_insert_id] ExecuteOptions fetch_last_insert_id */ /** @@ -97201,6 +97477,14 @@ export const query = $root.query = (() => { */ ExecuteOptions.prototype.authoritative_timeout = null; + /** + * ExecuteOptions fetch_last_insert_id. + * @member {boolean} fetch_last_insert_id + * @memberof query.ExecuteOptions + * @instance + */ + ExecuteOptions.prototype.fetch_last_insert_id = false; + // OneOf field names bound to virtual getters and setters let $oneOfFields; @@ -97269,6 +97553,8 @@ export const query = $root.query = (() => { writer.uint32(/* id 16, wireType 2 =*/130).string(message.priority); if (message.authoritative_timeout != null && Object.hasOwnProperty.call(message, "authoritative_timeout")) writer.uint32(/* id 17, wireType 0 =*/136).int64(message.authoritative_timeout); + if (message.fetch_last_insert_id != null && Object.hasOwnProperty.call(message, "fetch_last_insert_id")) + writer.uint32(/* id 18, wireType 0 =*/144).bool(message.fetch_last_insert_id); return writer; }; @@ -97362,6 +97648,10 @@ export const query = $root.query = (() => { message.authoritative_timeout = reader.int64(); break; } + case 18: { + message.fetch_last_insert_id = reader.bool(); + break; + } default: reader.skipType(tag & 7); break; @@ -97490,6 +97780,9 @@ export const query = $root.query = (() => { if (!$util.isInteger(message.authoritative_timeout) && !(message.authoritative_timeout && $util.isInteger(message.authoritative_timeout.low) && $util.isInteger(message.authoritative_timeout.high))) return "authoritative_timeout: integer|Long expected"; } + if (message.fetch_last_insert_id != null && message.hasOwnProperty("fetch_last_insert_id")) + if (typeof message.fetch_last_insert_id !== "boolean") + return "fetch_last_insert_id: boolean expected"; return null; }; @@ -97702,6 +97995,8 @@ export const query = $root.query = (() => { message.authoritative_timeout = object.authoritative_timeout; else if (typeof object.authoritative_timeout === "object") message.authoritative_timeout = new $util.LongBits(object.authoritative_timeout.low >>> 0, object.authoritative_timeout.high >>> 0).toNumber(); + if (object.fetch_last_insert_id != null) + message.fetch_last_insert_id = Boolean(object.fetch_last_insert_id); return message; }; @@ -97736,6 +98031,7 @@ export const query = $root.query = (() => { object.consolidator = options.enums === String ? "CONSOLIDATOR_UNSPECIFIED" : 0; object.WorkloadName = ""; object.priority = ""; + object.fetch_last_insert_id = false; } if (message.included_fields != null && message.hasOwnProperty("included_fields")) object.included_fields = options.enums === String ? $root.query.ExecuteOptions.IncludedFields[message.included_fields] === undefined ? message.included_fields : $root.query.ExecuteOptions.IncludedFields[message.included_fields] : message.included_fields; @@ -97775,6 +98071,8 @@ export const query = $root.query = (() => { if (options.oneofs) object.timeout = "authoritative_timeout"; } + if (message.fetch_last_insert_id != null && message.hasOwnProperty("fetch_last_insert_id")) + object.fetch_last_insert_id = message.fetch_last_insert_id; return object; }; @@ -98250,6 +98548,7 @@ export const query = $root.query = (() => { case 4130: case 2083: case 2084: + case 2085: break; } if (message.table != null && message.hasOwnProperty("table")) @@ -98451,6 +98750,10 @@ export const query = $root.query = (() => { case 2084: message.type = 2084; break; + case "ROW_TUPLE": + case 2085: + message.type = 2085; + break; } if (object.table != null) message.table = String(object.table); @@ -98835,6 +99138,7 @@ export const query = $root.query = (() => { * @property {Array.|null} [rows] QueryResult rows * @property {string|null} [info] QueryResult info * @property {string|null} [session_state_changes] QueryResult session_state_changes + * @property {boolean|null} [insert_id_changed] QueryResult insert_id_changed */ /** @@ -98902,6 +99206,14 @@ export const query = $root.query = (() => { */ QueryResult.prototype.session_state_changes = ""; + /** + * QueryResult insert_id_changed. + * @member {boolean} insert_id_changed + * @memberof query.QueryResult + * @instance + */ + QueryResult.prototype.insert_id_changed = false; + /** * Creates a new QueryResult instance using the specified properties. * @function create @@ -98940,6 +99252,8 @@ export const query = $root.query = (() => { writer.uint32(/* id 6, wireType 2 =*/50).string(message.info); if (message.session_state_changes != null && Object.hasOwnProperty.call(message, "session_state_changes")) writer.uint32(/* id 7, wireType 2 =*/58).string(message.session_state_changes); + if (message.insert_id_changed != null && Object.hasOwnProperty.call(message, "insert_id_changed")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.insert_id_changed); return writer; }; @@ -99002,6 +99316,10 @@ export const query = $root.query = (() => { message.session_state_changes = reader.string(); break; } + case 8: { + message.insert_id_changed = reader.bool(); + break; + } default: reader.skipType(tag & 7); break; @@ -99067,6 +99385,9 @@ export const query = $root.query = (() => { if (message.session_state_changes != null && message.hasOwnProperty("session_state_changes")) if (!$util.isString(message.session_state_changes)) return "session_state_changes: string expected"; + if (message.insert_id_changed != null && message.hasOwnProperty("insert_id_changed")) + if (typeof message.insert_id_changed !== "boolean") + return "insert_id_changed: boolean expected"; return null; }; @@ -99124,6 +99445,8 @@ export const query = $root.query = (() => { message.info = String(object.info); if (object.session_state_changes != null) message.session_state_changes = String(object.session_state_changes); + if (object.insert_id_changed != null) + message.insert_id_changed = Boolean(object.insert_id_changed); return message; }; @@ -99157,6 +99480,7 @@ export const query = $root.query = (() => { object.insert_id = options.longs === String ? "0" : 0; object.info = ""; object.session_state_changes = ""; + object.insert_id_changed = false; } if (message.fields && message.fields.length) { object.fields = []; @@ -99182,6 +99506,8 @@ export const query = $root.query = (() => { object.info = message.info; if (message.session_state_changes != null && message.hasOwnProperty("session_state_changes")) object.session_state_changes = message.session_state_changes; + if (message.insert_id_changed != null && message.hasOwnProperty("insert_id_changed")) + object.insert_id_changed = message.insert_id_changed; return object; }; @@ -115688,6 +116014,7 @@ export const query = $root.query = (() => { case 4130: case 2083: case 2084: + case 2085: break; } return null; @@ -115864,6 +116191,10 @@ export const query = $root.query = (() => { case 2084: message.return_type = 2084; break; + case "ROW_TUPLE": + case 2085: + message.return_type = 2085; + break; } return message; }; @@ -117164,7 +117495,6 @@ export const replicationdata = $root.replicationdata = (() => { * @interface IStopReplicationStatus * @property {replicationdata.IStatus|null} [before] StopReplicationStatus before * @property {replicationdata.IStatus|null} [after] StopReplicationStatus after - * @property {boolean|null} [backup_running] StopReplicationStatus backup_running */ /** @@ -117198,14 +117528,6 @@ export const replicationdata = $root.replicationdata = (() => { */ StopReplicationStatus.prototype.after = null; - /** - * StopReplicationStatus backup_running. - * @member {boolean} backup_running - * @memberof replicationdata.StopReplicationStatus - * @instance - */ - StopReplicationStatus.prototype.backup_running = false; - /** * Creates a new StopReplicationStatus instance using the specified properties. * @function create @@ -117234,8 +117556,6 @@ export const replicationdata = $root.replicationdata = (() => { $root.replicationdata.Status.encode(message.before, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); if (message.after != null && Object.hasOwnProperty.call(message, "after")) $root.replicationdata.Status.encode(message.after, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.backup_running != null && Object.hasOwnProperty.call(message, "backup_running")) - writer.uint32(/* id 3, wireType 0 =*/24).bool(message.backup_running); return writer; }; @@ -117278,10 +117598,6 @@ export const replicationdata = $root.replicationdata = (() => { message.after = $root.replicationdata.Status.decode(reader, reader.uint32()); break; } - case 3: { - message.backup_running = reader.bool(); - break; - } default: reader.skipType(tag & 7); break; @@ -117327,9 +117643,6 @@ export const replicationdata = $root.replicationdata = (() => { if (error) return "after." + error; } - if (message.backup_running != null && message.hasOwnProperty("backup_running")) - if (typeof message.backup_running !== "boolean") - return "backup_running: boolean expected"; return null; }; @@ -117355,8 +117668,6 @@ export const replicationdata = $root.replicationdata = (() => { throw TypeError(".replicationdata.StopReplicationStatus.after: object expected"); message.after = $root.replicationdata.Status.fromObject(object.after); } - if (object.backup_running != null) - message.backup_running = Boolean(object.backup_running); return message; }; @@ -117376,14 +117687,11 @@ export const replicationdata = $root.replicationdata = (() => { if (options.defaults) { object.before = null; object.after = null; - object.backup_running = false; } if (message.before != null && message.hasOwnProperty("before")) object.before = $root.replicationdata.Status.toObject(message.before, options); if (message.after != null && message.hasOwnProperty("after")) object.after = $root.replicationdata.Status.toObject(message.after, options); - if (message.backup_running != null && message.hasOwnProperty("backup_running")) - object.backup_running = message.backup_running; return object; }; @@ -117708,6 +118016,7 @@ export const replicationdata = $root.replicationdata = (() => { * @property {number|null} [semi_sync_wait_for_replica_count] FullStatus semi_sync_wait_for_replica_count * @property {boolean|null} [super_read_only] FullStatus super_read_only * @property {replicationdata.IConfiguration|null} [replication_configuration] FullStatus replication_configuration + * @property {boolean|null} [disk_stalled] FullStatus disk_stalled */ /** @@ -117901,6 +118210,14 @@ export const replicationdata = $root.replicationdata = (() => { */ FullStatus.prototype.replication_configuration = null; + /** + * FullStatus disk_stalled. + * @member {boolean} disk_stalled + * @memberof replicationdata.FullStatus + * @instance + */ + FullStatus.prototype.disk_stalled = false; + /** * Creates a new FullStatus instance using the specified properties. * @function create @@ -117969,6 +118286,8 @@ export const replicationdata = $root.replicationdata = (() => { writer.uint32(/* id 21, wireType 0 =*/168).bool(message.super_read_only); if (message.replication_configuration != null && Object.hasOwnProperty.call(message, "replication_configuration")) $root.replicationdata.Configuration.encode(message.replication_configuration, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim(); + if (message.disk_stalled != null && Object.hasOwnProperty.call(message, "disk_stalled")) + writer.uint32(/* id 23, wireType 0 =*/184).bool(message.disk_stalled); return writer; }; @@ -118091,6 +118410,10 @@ export const replicationdata = $root.replicationdata = (() => { message.replication_configuration = $root.replicationdata.Configuration.decode(reader, reader.uint32()); break; } + case 23: { + message.disk_stalled = reader.bool(); + break; + } default: reader.skipType(tag & 7); break; @@ -118198,6 +118521,9 @@ export const replicationdata = $root.replicationdata = (() => { if (error) return "replication_configuration." + error; } + if (message.disk_stalled != null && message.hasOwnProperty("disk_stalled")) + if (typeof message.disk_stalled !== "boolean") + return "disk_stalled: boolean expected"; return null; }; @@ -118273,6 +118599,8 @@ export const replicationdata = $root.replicationdata = (() => { throw TypeError(".replicationdata.FullStatus.replication_configuration: object expected"); message.replication_configuration = $root.replicationdata.Configuration.fromObject(object.replication_configuration); } + if (object.disk_stalled != null) + message.disk_stalled = Boolean(object.disk_stalled); return message; }; @@ -118316,6 +118644,7 @@ export const replicationdata = $root.replicationdata = (() => { object.semi_sync_wait_for_replica_count = 0; object.super_read_only = false; object.replication_configuration = null; + object.disk_stalled = false; } if (message.server_id != null && message.hasOwnProperty("server_id")) object.server_id = message.server_id; @@ -118364,6 +118693,8 @@ export const replicationdata = $root.replicationdata = (() => { object.super_read_only = message.super_read_only; if (message.replication_configuration != null && message.hasOwnProperty("replication_configuration")) object.replication_configuration = $root.replicationdata.Configuration.toObject(message.replication_configuration, options); + if (message.disk_stalled != null && message.hasOwnProperty("disk_stalled")) + object.disk_stalled = message.disk_stalled; return object; }; @@ -119521,6 +119852,7 @@ export const vschema = $root.vschema = (() => { case 4130: case 2083: case 2084: + case 2085: break; } return null; @@ -119695,6 +120027,10 @@ export const vschema = $root.vschema = (() => { case 2084: message.tenant_id_column_type = 2084; break; + case "ROW_TUPLE": + case 2085: + message.tenant_id_column_type = 2085; + break; } return message; }; @@ -121031,12 +121367,7 @@ export const vschema = $root.vschema = (() => { // OneOf field names bound to virtual getters and setters let $oneOfFields; - /** - * Column _nullable. - * @member {"nullable"|undefined} _nullable - * @memberof vschema.Column - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(Column.prototype, "_nullable", { get: $util.oneOfGetter($oneOfFields = ["nullable"]), set: $util.oneOfSetter($oneOfFields) @@ -121237,6 +121568,7 @@ export const vschema = $root.vschema = (() => { case 4130: case 2083: case 2084: + case 2085: break; } if (message.invisible != null && message.hasOwnProperty("invisible")) @@ -121438,6 +121770,10 @@ export const vschema = $root.vschema = (() => { case 2084: message.type = 2084; break; + case "ROW_TUPLE": + case 2085: + message.type = 2085; + break; } if (object.invisible != null) message.invisible = Boolean(object.invisible); @@ -134006,12 +134342,7 @@ export const vtctldata = $root.vtctldata = (() => { // OneOf field names bound to virtual getters and setters let $oneOfFields; - /** - * BackupRequest _backup_engine. - * @member {"backup_engine"|undefined} _backup_engine - * @memberof vtctldata.BackupRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(BackupRequest.prototype, "_backup_engine", { get: $util.oneOfGetter($oneOfFields = ["backup_engine"]), set: $util.oneOfSetter($oneOfFields) @@ -138000,6 +138331,590 @@ export const vtctldata = $root.vtctldata = (() => { return CompleteSchemaMigrationResponse; })(); + vtctldata.CopySchemaShardRequest = (function() { + + /** + * Properties of a CopySchemaShardRequest. + * @memberof vtctldata + * @interface ICopySchemaShardRequest + * @property {topodata.ITabletAlias|null} [source_tablet_alias] CopySchemaShardRequest source_tablet_alias + * @property {Array.|null} [tables] CopySchemaShardRequest tables + * @property {Array.|null} [exclude_tables] CopySchemaShardRequest exclude_tables + * @property {boolean|null} [include_views] CopySchemaShardRequest include_views + * @property {boolean|null} [skip_verify] CopySchemaShardRequest skip_verify + * @property {vttime.IDuration|null} [wait_replicas_timeout] CopySchemaShardRequest wait_replicas_timeout + * @property {string|null} [destination_keyspace] CopySchemaShardRequest destination_keyspace + * @property {string|null} [destination_shard] CopySchemaShardRequest destination_shard + */ + + /** + * Constructs a new CopySchemaShardRequest. + * @memberof vtctldata + * @classdesc Represents a CopySchemaShardRequest. + * @implements ICopySchemaShardRequest + * @constructor + * @param {vtctldata.ICopySchemaShardRequest=} [properties] Properties to set + */ + function CopySchemaShardRequest(properties) { + this.tables = []; + this.exclude_tables = []; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * CopySchemaShardRequest source_tablet_alias. + * @member {topodata.ITabletAlias|null|undefined} source_tablet_alias + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.source_tablet_alias = null; + + /** + * CopySchemaShardRequest tables. + * @member {Array.} tables + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.tables = $util.emptyArray; + + /** + * CopySchemaShardRequest exclude_tables. + * @member {Array.} exclude_tables + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.exclude_tables = $util.emptyArray; + + /** + * CopySchemaShardRequest include_views. + * @member {boolean} include_views + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.include_views = false; + + /** + * CopySchemaShardRequest skip_verify. + * @member {boolean} skip_verify + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.skip_verify = false; + + /** + * CopySchemaShardRequest wait_replicas_timeout. + * @member {vttime.IDuration|null|undefined} wait_replicas_timeout + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.wait_replicas_timeout = null; + + /** + * CopySchemaShardRequest destination_keyspace. + * @member {string} destination_keyspace + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.destination_keyspace = ""; + + /** + * CopySchemaShardRequest destination_shard. + * @member {string} destination_shard + * @memberof vtctldata.CopySchemaShardRequest + * @instance + */ + CopySchemaShardRequest.prototype.destination_shard = ""; + + /** + * Creates a new CopySchemaShardRequest instance using the specified properties. + * @function create + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {vtctldata.ICopySchemaShardRequest=} [properties] Properties to set + * @returns {vtctldata.CopySchemaShardRequest} CopySchemaShardRequest instance + */ + CopySchemaShardRequest.create = function create(properties) { + return new CopySchemaShardRequest(properties); + }; + + /** + * Encodes the specified CopySchemaShardRequest message. Does not implicitly {@link vtctldata.CopySchemaShardRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {vtctldata.ICopySchemaShardRequest} message CopySchemaShardRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CopySchemaShardRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.source_tablet_alias != null && Object.hasOwnProperty.call(message, "source_tablet_alias")) + $root.topodata.TabletAlias.encode(message.source_tablet_alias, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.tables != null && message.tables.length) + for (let i = 0; i < message.tables.length; ++i) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.tables[i]); + if (message.exclude_tables != null && message.exclude_tables.length) + for (let i = 0; i < message.exclude_tables.length; ++i) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.exclude_tables[i]); + if (message.include_views != null && Object.hasOwnProperty.call(message, "include_views")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.include_views); + if (message.skip_verify != null && Object.hasOwnProperty.call(message, "skip_verify")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.skip_verify); + if (message.wait_replicas_timeout != null && Object.hasOwnProperty.call(message, "wait_replicas_timeout")) + $root.vttime.Duration.encode(message.wait_replicas_timeout, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.destination_keyspace != null && Object.hasOwnProperty.call(message, "destination_keyspace")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.destination_keyspace); + if (message.destination_shard != null && Object.hasOwnProperty.call(message, "destination_shard")) + writer.uint32(/* id 8, wireType 2 =*/66).string(message.destination_shard); + return writer; + }; + + /** + * Encodes the specified CopySchemaShardRequest message, length delimited. Does not implicitly {@link vtctldata.CopySchemaShardRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {vtctldata.ICopySchemaShardRequest} message CopySchemaShardRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CopySchemaShardRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CopySchemaShardRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.CopySchemaShardRequest} CopySchemaShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CopySchemaShardRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.CopySchemaShardRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.source_tablet_alias = $root.topodata.TabletAlias.decode(reader, reader.uint32()); + break; + } + case 2: { + if (!(message.tables && message.tables.length)) + message.tables = []; + message.tables.push(reader.string()); + break; + } + case 3: { + if (!(message.exclude_tables && message.exclude_tables.length)) + message.exclude_tables = []; + message.exclude_tables.push(reader.string()); + break; + } + case 4: { + message.include_views = reader.bool(); + break; + } + case 5: { + message.skip_verify = reader.bool(); + break; + } + case 6: { + message.wait_replicas_timeout = $root.vttime.Duration.decode(reader, reader.uint32()); + break; + } + case 7: { + message.destination_keyspace = reader.string(); + break; + } + case 8: { + message.destination_shard = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CopySchemaShardRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.CopySchemaShardRequest} CopySchemaShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CopySchemaShardRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CopySchemaShardRequest message. + * @function verify + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CopySchemaShardRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.source_tablet_alias != null && message.hasOwnProperty("source_tablet_alias")) { + let error = $root.topodata.TabletAlias.verify(message.source_tablet_alias); + if (error) + return "source_tablet_alias." + error; + } + if (message.tables != null && message.hasOwnProperty("tables")) { + if (!Array.isArray(message.tables)) + return "tables: array expected"; + for (let i = 0; i < message.tables.length; ++i) + if (!$util.isString(message.tables[i])) + return "tables: string[] expected"; + } + if (message.exclude_tables != null && message.hasOwnProperty("exclude_tables")) { + if (!Array.isArray(message.exclude_tables)) + return "exclude_tables: array expected"; + for (let i = 0; i < message.exclude_tables.length; ++i) + if (!$util.isString(message.exclude_tables[i])) + return "exclude_tables: string[] expected"; + } + if (message.include_views != null && message.hasOwnProperty("include_views")) + if (typeof message.include_views !== "boolean") + return "include_views: boolean expected"; + if (message.skip_verify != null && message.hasOwnProperty("skip_verify")) + if (typeof message.skip_verify !== "boolean") + return "skip_verify: boolean expected"; + if (message.wait_replicas_timeout != null && message.hasOwnProperty("wait_replicas_timeout")) { + let error = $root.vttime.Duration.verify(message.wait_replicas_timeout); + if (error) + return "wait_replicas_timeout." + error; + } + if (message.destination_keyspace != null && message.hasOwnProperty("destination_keyspace")) + if (!$util.isString(message.destination_keyspace)) + return "destination_keyspace: string expected"; + if (message.destination_shard != null && message.hasOwnProperty("destination_shard")) + if (!$util.isString(message.destination_shard)) + return "destination_shard: string expected"; + return null; + }; + + /** + * Creates a CopySchemaShardRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.CopySchemaShardRequest} CopySchemaShardRequest + */ + CopySchemaShardRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.CopySchemaShardRequest) + return object; + let message = new $root.vtctldata.CopySchemaShardRequest(); + if (object.source_tablet_alias != null) { + if (typeof object.source_tablet_alias !== "object") + throw TypeError(".vtctldata.CopySchemaShardRequest.source_tablet_alias: object expected"); + message.source_tablet_alias = $root.topodata.TabletAlias.fromObject(object.source_tablet_alias); + } + if (object.tables) { + if (!Array.isArray(object.tables)) + throw TypeError(".vtctldata.CopySchemaShardRequest.tables: array expected"); + message.tables = []; + for (let i = 0; i < object.tables.length; ++i) + message.tables[i] = String(object.tables[i]); + } + if (object.exclude_tables) { + if (!Array.isArray(object.exclude_tables)) + throw TypeError(".vtctldata.CopySchemaShardRequest.exclude_tables: array expected"); + message.exclude_tables = []; + for (let i = 0; i < object.exclude_tables.length; ++i) + message.exclude_tables[i] = String(object.exclude_tables[i]); + } + if (object.include_views != null) + message.include_views = Boolean(object.include_views); + if (object.skip_verify != null) + message.skip_verify = Boolean(object.skip_verify); + if (object.wait_replicas_timeout != null) { + if (typeof object.wait_replicas_timeout !== "object") + throw TypeError(".vtctldata.CopySchemaShardRequest.wait_replicas_timeout: object expected"); + message.wait_replicas_timeout = $root.vttime.Duration.fromObject(object.wait_replicas_timeout); + } + if (object.destination_keyspace != null) + message.destination_keyspace = String(object.destination_keyspace); + if (object.destination_shard != null) + message.destination_shard = String(object.destination_shard); + return message; + }; + + /** + * Creates a plain object from a CopySchemaShardRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {vtctldata.CopySchemaShardRequest} message CopySchemaShardRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CopySchemaShardRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.arrays || options.defaults) { + object.tables = []; + object.exclude_tables = []; + } + if (options.defaults) { + object.source_tablet_alias = null; + object.include_views = false; + object.skip_verify = false; + object.wait_replicas_timeout = null; + object.destination_keyspace = ""; + object.destination_shard = ""; + } + if (message.source_tablet_alias != null && message.hasOwnProperty("source_tablet_alias")) + object.source_tablet_alias = $root.topodata.TabletAlias.toObject(message.source_tablet_alias, options); + if (message.tables && message.tables.length) { + object.tables = []; + for (let j = 0; j < message.tables.length; ++j) + object.tables[j] = message.tables[j]; + } + if (message.exclude_tables && message.exclude_tables.length) { + object.exclude_tables = []; + for (let j = 0; j < message.exclude_tables.length; ++j) + object.exclude_tables[j] = message.exclude_tables[j]; + } + if (message.include_views != null && message.hasOwnProperty("include_views")) + object.include_views = message.include_views; + if (message.skip_verify != null && message.hasOwnProperty("skip_verify")) + object.skip_verify = message.skip_verify; + if (message.wait_replicas_timeout != null && message.hasOwnProperty("wait_replicas_timeout")) + object.wait_replicas_timeout = $root.vttime.Duration.toObject(message.wait_replicas_timeout, options); + if (message.destination_keyspace != null && message.hasOwnProperty("destination_keyspace")) + object.destination_keyspace = message.destination_keyspace; + if (message.destination_shard != null && message.hasOwnProperty("destination_shard")) + object.destination_shard = message.destination_shard; + return object; + }; + + /** + * Converts this CopySchemaShardRequest to JSON. + * @function toJSON + * @memberof vtctldata.CopySchemaShardRequest + * @instance + * @returns {Object.} JSON object + */ + CopySchemaShardRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for CopySchemaShardRequest + * @function getTypeUrl + * @memberof vtctldata.CopySchemaShardRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + CopySchemaShardRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.CopySchemaShardRequest"; + }; + + return CopySchemaShardRequest; + })(); + + vtctldata.CopySchemaShardResponse = (function() { + + /** + * Properties of a CopySchemaShardResponse. + * @memberof vtctldata + * @interface ICopySchemaShardResponse + */ + + /** + * Constructs a new CopySchemaShardResponse. + * @memberof vtctldata + * @classdesc Represents a CopySchemaShardResponse. + * @implements ICopySchemaShardResponse + * @constructor + * @param {vtctldata.ICopySchemaShardResponse=} [properties] Properties to set + */ + function CopySchemaShardResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new CopySchemaShardResponse instance using the specified properties. + * @function create + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {vtctldata.ICopySchemaShardResponse=} [properties] Properties to set + * @returns {vtctldata.CopySchemaShardResponse} CopySchemaShardResponse instance + */ + CopySchemaShardResponse.create = function create(properties) { + return new CopySchemaShardResponse(properties); + }; + + /** + * Encodes the specified CopySchemaShardResponse message. Does not implicitly {@link vtctldata.CopySchemaShardResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {vtctldata.ICopySchemaShardResponse} message CopySchemaShardResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CopySchemaShardResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified CopySchemaShardResponse message, length delimited. Does not implicitly {@link vtctldata.CopySchemaShardResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {vtctldata.ICopySchemaShardResponse} message CopySchemaShardResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CopySchemaShardResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CopySchemaShardResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.CopySchemaShardResponse} CopySchemaShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CopySchemaShardResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.CopySchemaShardResponse(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CopySchemaShardResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.CopySchemaShardResponse} CopySchemaShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CopySchemaShardResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CopySchemaShardResponse message. + * @function verify + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CopySchemaShardResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a CopySchemaShardResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.CopySchemaShardResponse} CopySchemaShardResponse + */ + CopySchemaShardResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.CopySchemaShardResponse) + return object; + return new $root.vtctldata.CopySchemaShardResponse(); + }; + + /** + * Creates a plain object from a CopySchemaShardResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {vtctldata.CopySchemaShardResponse} message CopySchemaShardResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CopySchemaShardResponse.toObject = function toObject() { + return {}; + }; + + /** + * Converts this CopySchemaShardResponse to JSON. + * @function toJSON + * @memberof vtctldata.CopySchemaShardResponse + * @instance + * @returns {Object.} JSON object + */ + CopySchemaShardResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for CopySchemaShardResponse + * @function getTypeUrl + * @memberof vtctldata.CopySchemaShardResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + CopySchemaShardResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.CopySchemaShardResponse"; + }; + + return CopySchemaShardResponse; + })(); + vtctldata.CreateKeyspaceRequest = (function() { /** @@ -161040,6 +161955,431 @@ export const vtctldata = $root.vtctldata = (() => { return LaunchSchemaMigrationResponse; })(); + vtctldata.LookupVindexCompleteRequest = (function() { + + /** + * Properties of a LookupVindexCompleteRequest. + * @memberof vtctldata + * @interface ILookupVindexCompleteRequest + * @property {string|null} [keyspace] LookupVindexCompleteRequest keyspace + * @property {string|null} [name] LookupVindexCompleteRequest name + * @property {string|null} [table_keyspace] LookupVindexCompleteRequest table_keyspace + */ + + /** + * Constructs a new LookupVindexCompleteRequest. + * @memberof vtctldata + * @classdesc Represents a LookupVindexCompleteRequest. + * @implements ILookupVindexCompleteRequest + * @constructor + * @param {vtctldata.ILookupVindexCompleteRequest=} [properties] Properties to set + */ + function LookupVindexCompleteRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LookupVindexCompleteRequest keyspace. + * @member {string} keyspace + * @memberof vtctldata.LookupVindexCompleteRequest + * @instance + */ + LookupVindexCompleteRequest.prototype.keyspace = ""; + + /** + * LookupVindexCompleteRequest name. + * @member {string} name + * @memberof vtctldata.LookupVindexCompleteRequest + * @instance + */ + LookupVindexCompleteRequest.prototype.name = ""; + + /** + * LookupVindexCompleteRequest table_keyspace. + * @member {string} table_keyspace + * @memberof vtctldata.LookupVindexCompleteRequest + * @instance + */ + LookupVindexCompleteRequest.prototype.table_keyspace = ""; + + /** + * Creates a new LookupVindexCompleteRequest instance using the specified properties. + * @function create + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {vtctldata.ILookupVindexCompleteRequest=} [properties] Properties to set + * @returns {vtctldata.LookupVindexCompleteRequest} LookupVindexCompleteRequest instance + */ + LookupVindexCompleteRequest.create = function create(properties) { + return new LookupVindexCompleteRequest(properties); + }; + + /** + * Encodes the specified LookupVindexCompleteRequest message. Does not implicitly {@link vtctldata.LookupVindexCompleteRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {vtctldata.ILookupVindexCompleteRequest} message LookupVindexCompleteRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexCompleteRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.keyspace); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.name); + if (message.table_keyspace != null && Object.hasOwnProperty.call(message, "table_keyspace")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.table_keyspace); + return writer; + }; + + /** + * Encodes the specified LookupVindexCompleteRequest message, length delimited. Does not implicitly {@link vtctldata.LookupVindexCompleteRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {vtctldata.ILookupVindexCompleteRequest} message LookupVindexCompleteRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexCompleteRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LookupVindexCompleteRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.LookupVindexCompleteRequest} LookupVindexCompleteRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexCompleteRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.LookupVindexCompleteRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.keyspace = reader.string(); + break; + } + case 2: { + message.name = reader.string(); + break; + } + case 3: { + message.table_keyspace = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LookupVindexCompleteRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.LookupVindexCompleteRequest} LookupVindexCompleteRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexCompleteRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LookupVindexCompleteRequest message. + * @function verify + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LookupVindexCompleteRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + if (!$util.isString(message.keyspace)) + return "keyspace: string expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.table_keyspace != null && message.hasOwnProperty("table_keyspace")) + if (!$util.isString(message.table_keyspace)) + return "table_keyspace: string expected"; + return null; + }; + + /** + * Creates a LookupVindexCompleteRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.LookupVindexCompleteRequest} LookupVindexCompleteRequest + */ + LookupVindexCompleteRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.LookupVindexCompleteRequest) + return object; + let message = new $root.vtctldata.LookupVindexCompleteRequest(); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.name != null) + message.name = String(object.name); + if (object.table_keyspace != null) + message.table_keyspace = String(object.table_keyspace); + return message; + }; + + /** + * Creates a plain object from a LookupVindexCompleteRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {vtctldata.LookupVindexCompleteRequest} message LookupVindexCompleteRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LookupVindexCompleteRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.keyspace = ""; + object.name = ""; + object.table_keyspace = ""; + } + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.table_keyspace != null && message.hasOwnProperty("table_keyspace")) + object.table_keyspace = message.table_keyspace; + return object; + }; + + /** + * Converts this LookupVindexCompleteRequest to JSON. + * @function toJSON + * @memberof vtctldata.LookupVindexCompleteRequest + * @instance + * @returns {Object.} JSON object + */ + LookupVindexCompleteRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for LookupVindexCompleteRequest + * @function getTypeUrl + * @memberof vtctldata.LookupVindexCompleteRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + LookupVindexCompleteRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.LookupVindexCompleteRequest"; + }; + + return LookupVindexCompleteRequest; + })(); + + vtctldata.LookupVindexCompleteResponse = (function() { + + /** + * Properties of a LookupVindexCompleteResponse. + * @memberof vtctldata + * @interface ILookupVindexCompleteResponse + */ + + /** + * Constructs a new LookupVindexCompleteResponse. + * @memberof vtctldata + * @classdesc Represents a LookupVindexCompleteResponse. + * @implements ILookupVindexCompleteResponse + * @constructor + * @param {vtctldata.ILookupVindexCompleteResponse=} [properties] Properties to set + */ + function LookupVindexCompleteResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new LookupVindexCompleteResponse instance using the specified properties. + * @function create + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {vtctldata.ILookupVindexCompleteResponse=} [properties] Properties to set + * @returns {vtctldata.LookupVindexCompleteResponse} LookupVindexCompleteResponse instance + */ + LookupVindexCompleteResponse.create = function create(properties) { + return new LookupVindexCompleteResponse(properties); + }; + + /** + * Encodes the specified LookupVindexCompleteResponse message. Does not implicitly {@link vtctldata.LookupVindexCompleteResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {vtctldata.ILookupVindexCompleteResponse} message LookupVindexCompleteResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexCompleteResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified LookupVindexCompleteResponse message, length delimited. Does not implicitly {@link vtctldata.LookupVindexCompleteResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {vtctldata.ILookupVindexCompleteResponse} message LookupVindexCompleteResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexCompleteResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LookupVindexCompleteResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.LookupVindexCompleteResponse} LookupVindexCompleteResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexCompleteResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.LookupVindexCompleteResponse(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LookupVindexCompleteResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.LookupVindexCompleteResponse} LookupVindexCompleteResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexCompleteResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LookupVindexCompleteResponse message. + * @function verify + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LookupVindexCompleteResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a LookupVindexCompleteResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.LookupVindexCompleteResponse} LookupVindexCompleteResponse + */ + LookupVindexCompleteResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.LookupVindexCompleteResponse) + return object; + return new $root.vtctldata.LookupVindexCompleteResponse(); + }; + + /** + * Creates a plain object from a LookupVindexCompleteResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {vtctldata.LookupVindexCompleteResponse} message LookupVindexCompleteResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LookupVindexCompleteResponse.toObject = function toObject() { + return {}; + }; + + /** + * Converts this LookupVindexCompleteResponse to JSON. + * @function toJSON + * @memberof vtctldata.LookupVindexCompleteResponse + * @instance + * @returns {Object.} JSON object + */ + LookupVindexCompleteResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for LookupVindexCompleteResponse + * @function getTypeUrl + * @memberof vtctldata.LookupVindexCompleteResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + LookupVindexCompleteResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.LookupVindexCompleteResponse"; + }; + + return LookupVindexCompleteResponse; + })(); + vtctldata.LookupVindexCreateRequest = (function() { /** @@ -161701,6 +163041,7 @@ export const vtctldata = $root.vtctldata = (() => { * @property {string|null} [keyspace] LookupVindexExternalizeRequest keyspace * @property {string|null} [name] LookupVindexExternalizeRequest name * @property {string|null} [table_keyspace] LookupVindexExternalizeRequest table_keyspace + * @property {boolean|null} [delete_workflow] LookupVindexExternalizeRequest delete_workflow */ /** @@ -161742,6 +163083,14 @@ export const vtctldata = $root.vtctldata = (() => { */ LookupVindexExternalizeRequest.prototype.table_keyspace = ""; + /** + * LookupVindexExternalizeRequest delete_workflow. + * @member {boolean} delete_workflow + * @memberof vtctldata.LookupVindexExternalizeRequest + * @instance + */ + LookupVindexExternalizeRequest.prototype.delete_workflow = false; + /** * Creates a new LookupVindexExternalizeRequest instance using the specified properties. * @function create @@ -161772,6 +163121,8 @@ export const vtctldata = $root.vtctldata = (() => { writer.uint32(/* id 2, wireType 2 =*/18).string(message.name); if (message.table_keyspace != null && Object.hasOwnProperty.call(message, "table_keyspace")) writer.uint32(/* id 3, wireType 2 =*/26).string(message.table_keyspace); + if (message.delete_workflow != null && Object.hasOwnProperty.call(message, "delete_workflow")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.delete_workflow); return writer; }; @@ -161818,6 +163169,10 @@ export const vtctldata = $root.vtctldata = (() => { message.table_keyspace = reader.string(); break; } + case 4: { + message.delete_workflow = reader.bool(); + break; + } default: reader.skipType(tag & 7); break; @@ -161862,6 +163217,9 @@ export const vtctldata = $root.vtctldata = (() => { if (message.table_keyspace != null && message.hasOwnProperty("table_keyspace")) if (!$util.isString(message.table_keyspace)) return "table_keyspace: string expected"; + if (message.delete_workflow != null && message.hasOwnProperty("delete_workflow")) + if (typeof message.delete_workflow !== "boolean") + return "delete_workflow: boolean expected"; return null; }; @@ -161883,6 +163241,8 @@ export const vtctldata = $root.vtctldata = (() => { message.name = String(object.name); if (object.table_keyspace != null) message.table_keyspace = String(object.table_keyspace); + if (object.delete_workflow != null) + message.delete_workflow = Boolean(object.delete_workflow); return message; }; @@ -161903,6 +163263,7 @@ export const vtctldata = $root.vtctldata = (() => { object.keyspace = ""; object.name = ""; object.table_keyspace = ""; + object.delete_workflow = false; } if (message.keyspace != null && message.hasOwnProperty("keyspace")) object.keyspace = message.keyspace; @@ -161910,6 +163271,8 @@ export const vtctldata = $root.vtctldata = (() => { object.name = message.name; if (message.table_keyspace != null && message.hasOwnProperty("table_keyspace")) object.table_keyspace = message.table_keyspace; + if (message.delete_workflow != null && message.hasOwnProperty("delete_workflow")) + object.delete_workflow = message.delete_workflow; return object; }; @@ -161948,6 +163311,7 @@ export const vtctldata = $root.vtctldata = (() => { * Properties of a LookupVindexExternalizeResponse. * @memberof vtctldata * @interface ILookupVindexExternalizeResponse + * @property {boolean|null} [workflow_stopped] LookupVindexExternalizeResponse workflow_stopped * @property {boolean|null} [workflow_deleted] LookupVindexExternalizeResponse workflow_deleted */ @@ -161966,6 +163330,14 @@ export const vtctldata = $root.vtctldata = (() => { this[keys[i]] = properties[keys[i]]; } + /** + * LookupVindexExternalizeResponse workflow_stopped. + * @member {boolean} workflow_stopped + * @memberof vtctldata.LookupVindexExternalizeResponse + * @instance + */ + LookupVindexExternalizeResponse.prototype.workflow_stopped = false; + /** * LookupVindexExternalizeResponse workflow_deleted. * @member {boolean} workflow_deleted @@ -161998,8 +163370,10 @@ export const vtctldata = $root.vtctldata = (() => { LookupVindexExternalizeResponse.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); + if (message.workflow_stopped != null && Object.hasOwnProperty.call(message, "workflow_stopped")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.workflow_stopped); if (message.workflow_deleted != null && Object.hasOwnProperty.call(message, "workflow_deleted")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.workflow_deleted); + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.workflow_deleted); return writer; }; @@ -162035,6 +163409,10 @@ export const vtctldata = $root.vtctldata = (() => { let tag = reader.uint32(); switch (tag >>> 3) { case 1: { + message.workflow_stopped = reader.bool(); + break; + } + case 2: { message.workflow_deleted = reader.bool(); break; } @@ -162073,6 +163451,9 @@ export const vtctldata = $root.vtctldata = (() => { LookupVindexExternalizeResponse.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; + if (message.workflow_stopped != null && message.hasOwnProperty("workflow_stopped")) + if (typeof message.workflow_stopped !== "boolean") + return "workflow_stopped: boolean expected"; if (message.workflow_deleted != null && message.hasOwnProperty("workflow_deleted")) if (typeof message.workflow_deleted !== "boolean") return "workflow_deleted: boolean expected"; @@ -162091,6 +163472,8 @@ export const vtctldata = $root.vtctldata = (() => { if (object instanceof $root.vtctldata.LookupVindexExternalizeResponse) return object; let message = new $root.vtctldata.LookupVindexExternalizeResponse(); + if (object.workflow_stopped != null) + message.workflow_stopped = Boolean(object.workflow_stopped); if (object.workflow_deleted != null) message.workflow_deleted = Boolean(object.workflow_deleted); return message; @@ -162109,8 +163492,12 @@ export const vtctldata = $root.vtctldata = (() => { if (!options) options = {}; let object = {}; - if (options.defaults) + if (options.defaults) { + object.workflow_stopped = false; object.workflow_deleted = false; + } + if (message.workflow_stopped != null && message.hasOwnProperty("workflow_stopped")) + object.workflow_stopped = message.workflow_stopped; if (message.workflow_deleted != null && message.hasOwnProperty("workflow_deleted")) object.workflow_deleted = message.workflow_deleted; return object; @@ -162145,6 +163532,431 @@ export const vtctldata = $root.vtctldata = (() => { return LookupVindexExternalizeResponse; })(); + vtctldata.LookupVindexInternalizeRequest = (function() { + + /** + * Properties of a LookupVindexInternalizeRequest. + * @memberof vtctldata + * @interface ILookupVindexInternalizeRequest + * @property {string|null} [keyspace] LookupVindexInternalizeRequest keyspace + * @property {string|null} [name] LookupVindexInternalizeRequest name + * @property {string|null} [table_keyspace] LookupVindexInternalizeRequest table_keyspace + */ + + /** + * Constructs a new LookupVindexInternalizeRequest. + * @memberof vtctldata + * @classdesc Represents a LookupVindexInternalizeRequest. + * @implements ILookupVindexInternalizeRequest + * @constructor + * @param {vtctldata.ILookupVindexInternalizeRequest=} [properties] Properties to set + */ + function LookupVindexInternalizeRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LookupVindexInternalizeRequest keyspace. + * @member {string} keyspace + * @memberof vtctldata.LookupVindexInternalizeRequest + * @instance + */ + LookupVindexInternalizeRequest.prototype.keyspace = ""; + + /** + * LookupVindexInternalizeRequest name. + * @member {string} name + * @memberof vtctldata.LookupVindexInternalizeRequest + * @instance + */ + LookupVindexInternalizeRequest.prototype.name = ""; + + /** + * LookupVindexInternalizeRequest table_keyspace. + * @member {string} table_keyspace + * @memberof vtctldata.LookupVindexInternalizeRequest + * @instance + */ + LookupVindexInternalizeRequest.prototype.table_keyspace = ""; + + /** + * Creates a new LookupVindexInternalizeRequest instance using the specified properties. + * @function create + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {vtctldata.ILookupVindexInternalizeRequest=} [properties] Properties to set + * @returns {vtctldata.LookupVindexInternalizeRequest} LookupVindexInternalizeRequest instance + */ + LookupVindexInternalizeRequest.create = function create(properties) { + return new LookupVindexInternalizeRequest(properties); + }; + + /** + * Encodes the specified LookupVindexInternalizeRequest message. Does not implicitly {@link vtctldata.LookupVindexInternalizeRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {vtctldata.ILookupVindexInternalizeRequest} message LookupVindexInternalizeRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexInternalizeRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.keyspace); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.name); + if (message.table_keyspace != null && Object.hasOwnProperty.call(message, "table_keyspace")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.table_keyspace); + return writer; + }; + + /** + * Encodes the specified LookupVindexInternalizeRequest message, length delimited. Does not implicitly {@link vtctldata.LookupVindexInternalizeRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {vtctldata.ILookupVindexInternalizeRequest} message LookupVindexInternalizeRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexInternalizeRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LookupVindexInternalizeRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.LookupVindexInternalizeRequest} LookupVindexInternalizeRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexInternalizeRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.LookupVindexInternalizeRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.keyspace = reader.string(); + break; + } + case 2: { + message.name = reader.string(); + break; + } + case 3: { + message.table_keyspace = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LookupVindexInternalizeRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.LookupVindexInternalizeRequest} LookupVindexInternalizeRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexInternalizeRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LookupVindexInternalizeRequest message. + * @function verify + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LookupVindexInternalizeRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + if (!$util.isString(message.keyspace)) + return "keyspace: string expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.table_keyspace != null && message.hasOwnProperty("table_keyspace")) + if (!$util.isString(message.table_keyspace)) + return "table_keyspace: string expected"; + return null; + }; + + /** + * Creates a LookupVindexInternalizeRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.LookupVindexInternalizeRequest} LookupVindexInternalizeRequest + */ + LookupVindexInternalizeRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.LookupVindexInternalizeRequest) + return object; + let message = new $root.vtctldata.LookupVindexInternalizeRequest(); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.name != null) + message.name = String(object.name); + if (object.table_keyspace != null) + message.table_keyspace = String(object.table_keyspace); + return message; + }; + + /** + * Creates a plain object from a LookupVindexInternalizeRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {vtctldata.LookupVindexInternalizeRequest} message LookupVindexInternalizeRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LookupVindexInternalizeRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.keyspace = ""; + object.name = ""; + object.table_keyspace = ""; + } + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.table_keyspace != null && message.hasOwnProperty("table_keyspace")) + object.table_keyspace = message.table_keyspace; + return object; + }; + + /** + * Converts this LookupVindexInternalizeRequest to JSON. + * @function toJSON + * @memberof vtctldata.LookupVindexInternalizeRequest + * @instance + * @returns {Object.} JSON object + */ + LookupVindexInternalizeRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for LookupVindexInternalizeRequest + * @function getTypeUrl + * @memberof vtctldata.LookupVindexInternalizeRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + LookupVindexInternalizeRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.LookupVindexInternalizeRequest"; + }; + + return LookupVindexInternalizeRequest; + })(); + + vtctldata.LookupVindexInternalizeResponse = (function() { + + /** + * Properties of a LookupVindexInternalizeResponse. + * @memberof vtctldata + * @interface ILookupVindexInternalizeResponse + */ + + /** + * Constructs a new LookupVindexInternalizeResponse. + * @memberof vtctldata + * @classdesc Represents a LookupVindexInternalizeResponse. + * @implements ILookupVindexInternalizeResponse + * @constructor + * @param {vtctldata.ILookupVindexInternalizeResponse=} [properties] Properties to set + */ + function LookupVindexInternalizeResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new LookupVindexInternalizeResponse instance using the specified properties. + * @function create + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {vtctldata.ILookupVindexInternalizeResponse=} [properties] Properties to set + * @returns {vtctldata.LookupVindexInternalizeResponse} LookupVindexInternalizeResponse instance + */ + LookupVindexInternalizeResponse.create = function create(properties) { + return new LookupVindexInternalizeResponse(properties); + }; + + /** + * Encodes the specified LookupVindexInternalizeResponse message. Does not implicitly {@link vtctldata.LookupVindexInternalizeResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {vtctldata.ILookupVindexInternalizeResponse} message LookupVindexInternalizeResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexInternalizeResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified LookupVindexInternalizeResponse message, length delimited. Does not implicitly {@link vtctldata.LookupVindexInternalizeResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {vtctldata.ILookupVindexInternalizeResponse} message LookupVindexInternalizeResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LookupVindexInternalizeResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LookupVindexInternalizeResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.LookupVindexInternalizeResponse} LookupVindexInternalizeResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexInternalizeResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.LookupVindexInternalizeResponse(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LookupVindexInternalizeResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.LookupVindexInternalizeResponse} LookupVindexInternalizeResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LookupVindexInternalizeResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LookupVindexInternalizeResponse message. + * @function verify + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LookupVindexInternalizeResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a LookupVindexInternalizeResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.LookupVindexInternalizeResponse} LookupVindexInternalizeResponse + */ + LookupVindexInternalizeResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.LookupVindexInternalizeResponse) + return object; + return new $root.vtctldata.LookupVindexInternalizeResponse(); + }; + + /** + * Creates a plain object from a LookupVindexInternalizeResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {vtctldata.LookupVindexInternalizeResponse} message LookupVindexInternalizeResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LookupVindexInternalizeResponse.toObject = function toObject() { + return {}; + }; + + /** + * Converts this LookupVindexInternalizeResponse to JSON. + * @function toJSON + * @memberof vtctldata.LookupVindexInternalizeResponse + * @instance + * @returns {Object.} JSON object + */ + LookupVindexInternalizeResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for LookupVindexInternalizeResponse + * @function getTypeUrl + * @memberof vtctldata.LookupVindexInternalizeResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + LookupVindexInternalizeResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.LookupVindexInternalizeResponse"; + }; + + return LookupVindexInternalizeResponse; + })(); + vtctldata.MaterializeCreateRequest = (function() { /** @@ -184423,6 +186235,424 @@ export const vtctldata = $root.vtctldata = (() => { return ValidateKeyspaceResponse; })(); + vtctldata.ValidatePermissionsKeyspaceRequest = (function() { + + /** + * Properties of a ValidatePermissionsKeyspaceRequest. + * @memberof vtctldata + * @interface IValidatePermissionsKeyspaceRequest + * @property {string|null} [keyspace] ValidatePermissionsKeyspaceRequest keyspace + * @property {Array.|null} [shards] ValidatePermissionsKeyspaceRequest shards + */ + + /** + * Constructs a new ValidatePermissionsKeyspaceRequest. + * @memberof vtctldata + * @classdesc Represents a ValidatePermissionsKeyspaceRequest. + * @implements IValidatePermissionsKeyspaceRequest + * @constructor + * @param {vtctldata.IValidatePermissionsKeyspaceRequest=} [properties] Properties to set + */ + function ValidatePermissionsKeyspaceRequest(properties) { + this.shards = []; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ValidatePermissionsKeyspaceRequest keyspace. + * @member {string} keyspace + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @instance + */ + ValidatePermissionsKeyspaceRequest.prototype.keyspace = ""; + + /** + * ValidatePermissionsKeyspaceRequest shards. + * @member {Array.} shards + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @instance + */ + ValidatePermissionsKeyspaceRequest.prototype.shards = $util.emptyArray; + + /** + * Creates a new ValidatePermissionsKeyspaceRequest instance using the specified properties. + * @function create + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {vtctldata.IValidatePermissionsKeyspaceRequest=} [properties] Properties to set + * @returns {vtctldata.ValidatePermissionsKeyspaceRequest} ValidatePermissionsKeyspaceRequest instance + */ + ValidatePermissionsKeyspaceRequest.create = function create(properties) { + return new ValidatePermissionsKeyspaceRequest(properties); + }; + + /** + * Encodes the specified ValidatePermissionsKeyspaceRequest message. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {vtctldata.IValidatePermissionsKeyspaceRequest} message ValidatePermissionsKeyspaceRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ValidatePermissionsKeyspaceRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.keyspace); + if (message.shards != null && message.shards.length) + for (let i = 0; i < message.shards.length; ++i) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.shards[i]); + return writer; + }; + + /** + * Encodes the specified ValidatePermissionsKeyspaceRequest message, length delimited. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {vtctldata.IValidatePermissionsKeyspaceRequest} message ValidatePermissionsKeyspaceRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ValidatePermissionsKeyspaceRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ValidatePermissionsKeyspaceRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ValidatePermissionsKeyspaceRequest} ValidatePermissionsKeyspaceRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ValidatePermissionsKeyspaceRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ValidatePermissionsKeyspaceRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.keyspace = reader.string(); + break; + } + case 2: { + if (!(message.shards && message.shards.length)) + message.shards = []; + message.shards.push(reader.string()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ValidatePermissionsKeyspaceRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ValidatePermissionsKeyspaceRequest} ValidatePermissionsKeyspaceRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ValidatePermissionsKeyspaceRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ValidatePermissionsKeyspaceRequest message. + * @function verify + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ValidatePermissionsKeyspaceRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + if (!$util.isString(message.keyspace)) + return "keyspace: string expected"; + if (message.shards != null && message.hasOwnProperty("shards")) { + if (!Array.isArray(message.shards)) + return "shards: array expected"; + for (let i = 0; i < message.shards.length; ++i) + if (!$util.isString(message.shards[i])) + return "shards: string[] expected"; + } + return null; + }; + + /** + * Creates a ValidatePermissionsKeyspaceRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ValidatePermissionsKeyspaceRequest} ValidatePermissionsKeyspaceRequest + */ + ValidatePermissionsKeyspaceRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ValidatePermissionsKeyspaceRequest) + return object; + let message = new $root.vtctldata.ValidatePermissionsKeyspaceRequest(); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.shards) { + if (!Array.isArray(object.shards)) + throw TypeError(".vtctldata.ValidatePermissionsKeyspaceRequest.shards: array expected"); + message.shards = []; + for (let i = 0; i < object.shards.length; ++i) + message.shards[i] = String(object.shards[i]); + } + return message; + }; + + /** + * Creates a plain object from a ValidatePermissionsKeyspaceRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {vtctldata.ValidatePermissionsKeyspaceRequest} message ValidatePermissionsKeyspaceRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ValidatePermissionsKeyspaceRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.arrays || options.defaults) + object.shards = []; + if (options.defaults) + object.keyspace = ""; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.shards && message.shards.length) { + object.shards = []; + for (let j = 0; j < message.shards.length; ++j) + object.shards[j] = message.shards[j]; + } + return object; + }; + + /** + * Converts this ValidatePermissionsKeyspaceRequest to JSON. + * @function toJSON + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @instance + * @returns {Object.} JSON object + */ + ValidatePermissionsKeyspaceRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ValidatePermissionsKeyspaceRequest + * @function getTypeUrl + * @memberof vtctldata.ValidatePermissionsKeyspaceRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ValidatePermissionsKeyspaceRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.ValidatePermissionsKeyspaceRequest"; + }; + + return ValidatePermissionsKeyspaceRequest; + })(); + + vtctldata.ValidatePermissionsKeyspaceResponse = (function() { + + /** + * Properties of a ValidatePermissionsKeyspaceResponse. + * @memberof vtctldata + * @interface IValidatePermissionsKeyspaceResponse + */ + + /** + * Constructs a new ValidatePermissionsKeyspaceResponse. + * @memberof vtctldata + * @classdesc Represents a ValidatePermissionsKeyspaceResponse. + * @implements IValidatePermissionsKeyspaceResponse + * @constructor + * @param {vtctldata.IValidatePermissionsKeyspaceResponse=} [properties] Properties to set + */ + function ValidatePermissionsKeyspaceResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new ValidatePermissionsKeyspaceResponse instance using the specified properties. + * @function create + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {vtctldata.IValidatePermissionsKeyspaceResponse=} [properties] Properties to set + * @returns {vtctldata.ValidatePermissionsKeyspaceResponse} ValidatePermissionsKeyspaceResponse instance + */ + ValidatePermissionsKeyspaceResponse.create = function create(properties) { + return new ValidatePermissionsKeyspaceResponse(properties); + }; + + /** + * Encodes the specified ValidatePermissionsKeyspaceResponse message. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {vtctldata.IValidatePermissionsKeyspaceResponse} message ValidatePermissionsKeyspaceResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ValidatePermissionsKeyspaceResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified ValidatePermissionsKeyspaceResponse message, length delimited. Does not implicitly {@link vtctldata.ValidatePermissionsKeyspaceResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {vtctldata.IValidatePermissionsKeyspaceResponse} message ValidatePermissionsKeyspaceResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ValidatePermissionsKeyspaceResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ValidatePermissionsKeyspaceResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ValidatePermissionsKeyspaceResponse} ValidatePermissionsKeyspaceResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ValidatePermissionsKeyspaceResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ValidatePermissionsKeyspaceResponse(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ValidatePermissionsKeyspaceResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ValidatePermissionsKeyspaceResponse} ValidatePermissionsKeyspaceResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ValidatePermissionsKeyspaceResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ValidatePermissionsKeyspaceResponse message. + * @function verify + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ValidatePermissionsKeyspaceResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a ValidatePermissionsKeyspaceResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ValidatePermissionsKeyspaceResponse} ValidatePermissionsKeyspaceResponse + */ + ValidatePermissionsKeyspaceResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ValidatePermissionsKeyspaceResponse) + return object; + return new $root.vtctldata.ValidatePermissionsKeyspaceResponse(); + }; + + /** + * Creates a plain object from a ValidatePermissionsKeyspaceResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {vtctldata.ValidatePermissionsKeyspaceResponse} message ValidatePermissionsKeyspaceResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ValidatePermissionsKeyspaceResponse.toObject = function toObject() { + return {}; + }; + + /** + * Converts this ValidatePermissionsKeyspaceResponse to JSON. + * @function toJSON + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @instance + * @returns {Object.} JSON object + */ + ValidatePermissionsKeyspaceResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ValidatePermissionsKeyspaceResponse + * @function getTypeUrl + * @memberof vtctldata.ValidatePermissionsKeyspaceResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ValidatePermissionsKeyspaceResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.ValidatePermissionsKeyspaceResponse"; + }; + + return ValidatePermissionsKeyspaceResponse; + })(); + vtctldata.ValidateSchemaKeyspaceRequest = (function() { /** @@ -184434,6 +186664,7 @@ export const vtctldata = $root.vtctldata = (() => { * @property {boolean|null} [include_views] ValidateSchemaKeyspaceRequest include_views * @property {boolean|null} [skip_no_primary] ValidateSchemaKeyspaceRequest skip_no_primary * @property {boolean|null} [include_vschema] ValidateSchemaKeyspaceRequest include_vschema + * @property {Array.|null} [shards] ValidateSchemaKeyspaceRequest shards */ /** @@ -184446,6 +186677,7 @@ export const vtctldata = $root.vtctldata = (() => { */ function ValidateSchemaKeyspaceRequest(properties) { this.exclude_tables = []; + this.shards = []; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -184492,6 +186724,14 @@ export const vtctldata = $root.vtctldata = (() => { */ ValidateSchemaKeyspaceRequest.prototype.include_vschema = false; + /** + * ValidateSchemaKeyspaceRequest shards. + * @member {Array.} shards + * @memberof vtctldata.ValidateSchemaKeyspaceRequest + * @instance + */ + ValidateSchemaKeyspaceRequest.prototype.shards = $util.emptyArray; + /** * Creates a new ValidateSchemaKeyspaceRequest instance using the specified properties. * @function create @@ -184527,6 +186767,9 @@ export const vtctldata = $root.vtctldata = (() => { writer.uint32(/* id 4, wireType 0 =*/32).bool(message.skip_no_primary); if (message.include_vschema != null && Object.hasOwnProperty.call(message, "include_vschema")) writer.uint32(/* id 5, wireType 0 =*/40).bool(message.include_vschema); + if (message.shards != null && message.shards.length) + for (let i = 0; i < message.shards.length; ++i) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.shards[i]); return writer; }; @@ -184583,6 +186826,12 @@ export const vtctldata = $root.vtctldata = (() => { message.include_vschema = reader.bool(); break; } + case 6: { + if (!(message.shards && message.shards.length)) + message.shards = []; + message.shards.push(reader.string()); + break; + } default: reader.skipType(tag & 7); break; @@ -184637,6 +186886,13 @@ export const vtctldata = $root.vtctldata = (() => { if (message.include_vschema != null && message.hasOwnProperty("include_vschema")) if (typeof message.include_vschema !== "boolean") return "include_vschema: boolean expected"; + if (message.shards != null && message.hasOwnProperty("shards")) { + if (!Array.isArray(message.shards)) + return "shards: array expected"; + for (let i = 0; i < message.shards.length; ++i) + if (!$util.isString(message.shards[i])) + return "shards: string[] expected"; + } return null; }; @@ -184667,6 +186923,13 @@ export const vtctldata = $root.vtctldata = (() => { message.skip_no_primary = Boolean(object.skip_no_primary); if (object.include_vschema != null) message.include_vschema = Boolean(object.include_vschema); + if (object.shards) { + if (!Array.isArray(object.shards)) + throw TypeError(".vtctldata.ValidateSchemaKeyspaceRequest.shards: array expected"); + message.shards = []; + for (let i = 0; i < object.shards.length; ++i) + message.shards[i] = String(object.shards[i]); + } return message; }; @@ -184683,8 +186946,10 @@ export const vtctldata = $root.vtctldata = (() => { if (!options) options = {}; let object = {}; - if (options.arrays || options.defaults) + if (options.arrays || options.defaults) { object.exclude_tables = []; + object.shards = []; + } if (options.defaults) { object.keyspace = ""; object.include_views = false; @@ -184704,6 +186969,11 @@ export const vtctldata = $root.vtctldata = (() => { object.skip_no_primary = message.skip_no_primary; if (message.include_vschema != null && message.hasOwnProperty("include_vschema")) object.include_vschema = message.include_vschema; + if (message.shards && message.shards.length) { + object.shards = []; + for (let j = 0; j < message.shards.length; ++j) + object.shards[j] = message.shards[j]; + } return object; }; @@ -187244,12 +189514,7 @@ export const vtctldata = $root.vtctldata = (() => { // OneOf field names bound to virtual getters and setters let $oneOfFields; - /** - * VDiffCreateRequest _auto_start. - * @member {"auto_start"|undefined} _auto_start - * @memberof vtctldata.VDiffCreateRequest - * @instance - */ + // Virtual OneOf for proto3 optional field Object.defineProperty(VDiffCreateRequest.prototype, "_auto_start", { get: $util.oneOfGetter($oneOfFields = ["auto_start"]), set: $util.oneOfSetter($oneOfFields)